#246 Calendar of queer dates

This commit is contained in:
Avris 2021-08-14 16:22:30 +02:00
parent fc6ca5328e
commit fac7a757d2
19 changed files with 309 additions and 221 deletions

View File

@ -27,7 +27,8 @@
</template>
<script>
import { Day, iterateMonth, currentYear } from '../src/calendar';
import { Day, iterateMonth } from '../src/calendar/helpers';
import { currentYear } from '../src/calendar/calendar';
export default {
props: {
@ -70,14 +71,14 @@
return 'day';
}
if (this.currentYear.eventsByDate[d.toString()].some(e => e.length() === 1)) {
return 'day day-event day-event-single';
if (this.currentYear.eventsByDate[d.toString()].some(e => e.major)) {
return 'day day-event day-event-major';
}
return 'day day-event day-event-multi';
return 'day day-event day-event-minor';
},
getDayFlag(d) {
for (let event of (this.currentYear.eventsByDate[d.toString()] || []).filter(e => e.length() === 1)) {
for (let event of (this.currentYear.eventsByDate[d.toString()] || []).filter(e => e.major)) {
return `/flags/${event.flag}.png`;
}
return null;
@ -117,8 +118,8 @@
position: relative;
&.day-event {
cursor: pointer;
border: 1px solid $primary;
&.day-event-single {
border: 1px solid lighten($primary, 25%);
&.day-event-major {
background-color: $primary;
color: $white;
.day-number {

View File

@ -19,7 +19,8 @@
</template>
<script>
import { Day, currentYear } from '../src/calendar';
import { currentYear } from '../src/calendar/calendar';
import { Day } from '../src/calendar/helpers';
export default {
props: {

110
locale/_/events.js Normal file
View File

@ -0,0 +1,110 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
// months
new Event('pride_month', 'Progress Pride', 6, month, false),
new Event('trans_month', 'Transgender', 11, month, false),
// project celebrations
new Event('zaimki_birthday', null, 7, day(23), true),
// static date
new Event('agender_day', 'Agender', 5, day(19), true),
new Event('asexuality_day', 'Asexual', 4, day(6), true),
new Event('bisexuality_day', 'Bisexual', 9, day(23), true),
new Event('drag_day', '-Drag', 7, day(16), true),
new Event('idahobit', null, 5, day(17), true),
new Event('intersex_day', 'Intersex', 10, day(26), true),
new Event('intersex_remembrance_day', 'Intersex', 11, day(8), true),
new Event('lesbian_day', 'Lesbian', 10, day(8), true),
new Event('lesbian_visibility_day', 'Lesbian', 4, day(26), true),
new Event('coming_out_day', null, 10, day(11), true),
new Event('nonbinary_day', 'Nonbinary', 7, day(14), true),
new Event('pan_day', 'Pansexual', 5, day(24), true),
new Event('trans_remembrance_day', 'Transgender', 11, day(20), true),
new Event('trans_visibility_day', 'Transgender', 3, day(31), true),
new Event('zero_discrimination_day', null, 3, day(1), true),
new Event('polyamory_day', 'Polyamorous', 11, day(23), true),
// dynamic date
new Event('arospec_week', 'Aromantic', 2, week(function* (monthDays) {
let started = false;
for (let d of monthDays) {
if (!started && d.day > 14 && d.dayOfWeek === 7) {
started = true;
}
if (started) {
yield d;
}
}
}, false)),
new Event('asexual_week', 'Asexual', 10, week(function* (monthDays) {
let started = false;
for (let d of monthDays) {
if (!started && d.day >= 19 && d.dayOfWeek === 7) {
started = true;
}
if (started) {
yield d;
}
}
}, false)),
new Event('bisexual_week', 'Bisexual', 9, week(function* (monthDays) {
for (let d of monthDays) {
if (d.day >= 16 && d.day <= 22) {
yield d;
}
}
}, false)),
new Event('pronouns_day', null, 10, function* (monthDays) {
let wednesdays = 0;
for (let d of monthDays) {
if (d.dayOfWeek === 3) {
wednesdays++;
if (wednesdays === 3) {
yield d;
return;
}
}
}
}, true),
new Event('trans_week', 'Transgender', 11, week(function* (monthDays) {
for (let d of monthDays) {
if (d.day >= 13 && d.day <= 19) {
yield d;
}
}
}, false)),
new Event('trans_parent_day', 'Transgender', 11, week(function* (monthDays) {
for (let d of monthDays) {
if (d.dayOfWeek === 7) {
yield d;
return;
}
}
}, true)),
new Event('nonbinary_week', 'Nonbinary', 7, week(function* (monthDays) {
let buffer = [];
for (let d of monthDays) {
if (d.day >= 14) {
for (let dd of buffer) {
yield dd;
}
buffer = [];
yield d;
continue;
}
if (d.dayOfWeek === 1) {
buffer = [];
}
buffer.push(d);
}
}, false)),
];

5
locale/de/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/en/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/es/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/fr/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/nl/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/no/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

View File

@ -995,7 +995,7 @@ profile:
defaultPronoun: 'on_'
calendar:
enabled: true
enabled: false
route: 'kalendarz'
census:

10
locale/pl/events.js Normal file
View File

@ -0,0 +1,10 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
// namedays
new Event('nameday_andrea', null, 4, day(30), false),
// one-off events
new Event('pridemarch_warsaw', null, 1, dayYear(2, 2021), true),
new Event('pridemarch_warsaw', null, 1, dayYear(4, 2020), true),
];

View File

@ -1318,4 +1318,8 @@ calendar:
trans_parent_day: 'Dzień Rodzicielstwa Osób {/slowniki/terminologia#transpłciowość=Transpłciowych}'
nonbinary_week: 'Tydzień Świadomości nt. {/slowniki/terminologia#niebinarność=Niebinarności Płciowej}'
polyamory_day: 'Dzień {/slowniki/terminologia#poliamoria=Poliamorii}'
nameday_andrea: 'Imieniny: Andrea'
pridemarch_warsaw: 'Parada Równości w Warszawie \[test]'
banner: 'Obchodzimy właśnie'

5
locale/pt/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/ru/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/yi/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

5
locale/zh/events.js Normal file
View File

@ -0,0 +1,5 @@
import {Event, day, week, month, dayYear} from "../../src/calendar/helpers";
export default [
];

View File

@ -1,212 +0,0 @@
export class Day {
constructor(year, month, day, dayOfWeek) {
this.year = year;
this.month = month;
this.day = day;
this.dayOfWeek = dayOfWeek || new Date(year, month - 1, day).getDay() || 7;
}
static fromDate(date) {
return new Day(date.getFullYear(), date.getMonth() + 1, date.getDate());
}
static today() {
return Day.fromDate(new Date);
}
equals(other) {
return other && this.year === other.year && this.month === other.month && this.day === other.day;
}
toString() {
return `${this.year}-${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')}`;
}
}
export function* iterateMonth(year, month) {
for (let day = 1; day <= 31; day++) {
let d = new Date(year, month - 1, day);
if (d.getDate() !== day) { return; }
yield new Day(year, month, day, d.getDay() || 7);
}
}
export class Event {
constructor(name, flag, month, generator) {
this.name = name;
this.flag = flag;
this.month = month;
this.generator = generator;
this.daysMemoise = {}
}
getDays(year) {
if (this.daysMemoise[year] === undefined) {
this.daysMemoise[year] = [...this.generator(iterateMonth(year, this.month))];
}
return this.daysMemoise[year];
}
length() {
return [...this.getDays(2021)].length;
}
}
function day (dayOfMonth) {
function *internal (monthDays) {
for (let d of monthDays) {
if (d.day === dayOfMonth) {
yield d;
}
}
}
return internal;
}
function *month (monthDays) {
for (let d of monthDays) {
yield d;
}
}
function week (generator) {
function *internal (monthDays) {
let count = 0;
for (let d of generator(monthDays)) {
yield d;
count++;
if (count === 7) {
return;
}
}
}
return internal;
}
export const events = [
new Event('zaimki_birthday', null, 8, day(14)), // TODO
new Event('pride_month', 'Progress Pride', 6, month),
new Event('trans_month', 'Transgender', 11, month),
new Event('zaimki_birthday', null, 7, day(23)),
new Event('agender_day', 'Agender', 5, day(19)),
new Event('asexuality_day', 'Asexual', 4, day(6)),
new Event('bisexuality_day', 'Bisexual', 9, day(23)),
new Event('drag_day', '-Drag', 6, day(16)),
new Event('idahobit', null, 5, day(17)),
new Event('intersex_day', 'Intersex', 10, day(26)),
new Event('intersex_remembrance_day', 'Intersex', 11, day(8)),
new Event('lesbian_day', 'Lesbian', 10, day(8)),
new Event('lesbian_visibility_day', 'Lesbian', 4, day(26)),
new Event('coming_out_day', null, 10, day(11)),
new Event('nonbinary_day', 'Nonbinary', 7, day(14)),
new Event('pan_day', 'Pansexual', 5, day(24)),
new Event('trans_remembrance_day', 'Transgender', 11, day(20)),
new Event('trans_visibility_day', 'Transgender', 3, day(31)),
new Event('zero_discrimination_day', null, 3, day(1)),
new Event('polyamory_day', 'Polyamorous', 11, day(23)),
new Event('arospec_week', 'Aromantic', 2, week(function *(monthDays) {
let started = false;
for (let d of monthDays) {
if (!started && d.day > 14 && d.dayOfWeek === 7) {
started = true;
}
if (started) {
yield d;
}
}
})),
new Event('asexual_week', 'Asexual', 10, week(function *(monthDays) {
let started = false;
for (let d of monthDays) {
if (!started && d.day >= 19 && d.dayOfWeek === 7) {
started = true;
}
if (started) {
yield d;
}
}
})),
new Event('bisexual_week', 'Bisexual', 9, week(function *(monthDays) {
for (let d of monthDays) {
if (d.day >= 16 && d.day <= 22) {
yield d;
}
}
})),
new Event('pronouns_day', null, 10, function *(monthDays) {
let wednesdays = 0;
for (let d of monthDays) {
if (d.dayOfWeek === 3) {
wednesdays++;
if (wednesdays === 3) {
yield d;
return;
}
}
}
}),
new Event('trans_week', 'Transgender', 11, week(function *(monthDays) {
for (let d of monthDays) {
if (d.day >= 13 && d.day <= 19) {
yield d;
}
}
})),
new Event('trans_parent_day', 'Transgender', 9, week(function *(monthDays) {
for (let d of monthDays) {
if (d.dayOfWeek === 7) {
yield d;
return;
}
}
})),
new Event('nonbinary_week', 'Nonbinary', 7, week(function *(monthDays) {
let buffer = [];
for (let d of monthDays) {
if (d.day >= 14) {
for (let dd of buffer) {
yield dd;
}
buffer = [];
yield d;
continue;
}
if (d.dayOfWeek === 1) {
buffer = [];
}
buffer.push(d);
}
})),
];
export class Year {
constructor(year, events) {
this.year = year;
this.events = events;
this.eventsByDate = {};
for (let event of events) {
for (let d of event.getDays(year)) {
const k = d.toString();
if (this.eventsByDate[k] === undefined) { this.eventsByDate[k] = []; }
this.eventsByDate[k].push(event);
}
}
}
}
export const currentYear = new Year(new Date().getFullYear(), events);

8
src/calendar/calendar.js Normal file
View File

@ -0,0 +1,8 @@
import { Day, Calendar } from './helpers';
import internationalEvents from '../../locale/_/events';
import localEvents from '../../locale/pl/events';
export const currentYear = new Calendar(
Day.today().year,
[...internationalEvents, ...localEvents],
);

116
src/calendar/helpers.js Normal file
View File

@ -0,0 +1,116 @@
export class Day {
constructor(year, month, day, dayOfWeek) {
this.year = year;
this.month = month;
this.day = day;
this.dayOfWeek = dayOfWeek || new Date(year, month - 1, day).getDay() || 7;
}
static fromDate(date) {
return new Day(date.getFullYear(), date.getMonth() + 1, date.getDate());
}
static today() {
return Day.fromDate(new Date);
}
equals(other) {
return other && this.year === other.year && this.month === other.month && this.day === other.day;
}
toString() {
return `${this.year}-${this.month.toString().padStart(2, '0')}-${this.day.toString().padStart(2, '0')}`;
}
}
export function* iterateMonth(year, month) {
for (let day = 1; day <= 31; day++) {
let d = new Date(year, month - 1, day);
if (d.getDate() !== day) { return; }
yield new Day(year, month, day, d.getDay() || 7);
}
}
export class Event {
constructor(name, flag, month, generator, major) {
this.name = name;
this.flag = flag;
this.month = month;
this.generator = generator;
this.major = major;
this.daysMemoise = {}
}
getDays(year) {
if (this.daysMemoise[year] === undefined) {
this.daysMemoise[year] = [...this.generator(iterateMonth(year, this.month))];
}
return this.daysMemoise[year];
}
length() {
return [...this.getDays(2021)].length;
}
}
export function day (dayOfMonth) {
function *internal (monthDays) {
for (let d of monthDays) {
if (d.day === dayOfMonth) {
yield d;
}
}
}
return internal;
}
export function *month (monthDays) {
for (let d of monthDays) {
yield d;
}
}
export function week (generator) {
function *internal (monthDays) {
let count = 0;
for (let d of generator(monthDays)) {
yield d;
count++;
if (count === 7) {
return;
}
}
}
return internal;
}
export function dayYear (day, year) {
function *internal (monthDays) {
for (let d of monthDays) {
if (d.day === day && d.year === year) {
yield d;
}
}
}
return internal;
}
export class Calendar {
constructor(year, events) {
this.year = year;
this.events = events;
this.eventsByDate = {};
for (let event of events) {
for (let d of event.getDays(year)) {
const k = d.toString();
if (this.eventsByDate[k] === undefined) { this.eventsByDate[k] = []; }
this.eventsByDate[k].push(event);
}
}
}
}