Skip to content

Commit

Permalink
Leap day collapsible
Browse files Browse the repository at this point in the history
  • Loading branch information
Haxxer committed Nov 17, 2024
1 parent c811153 commit 12f61e4
Show file tree
Hide file tree
Showing 7 changed files with 432 additions and 576 deletions.
5 changes: 4 additions & 1 deletion resources/js/calendar/calendar_edit_page.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ export default (calendar_structure) => ({
window.static_data = _.set(window.static_data, key, _.cloneDeep(value));
}

console.log(window.static_data);
// First of many rules, I'm sure.
window.static_data.year_data.overflow = window.static_data.year_data.overflow
&& !window.static_data.year_data.leap_days.some(leapDay => leapDay.adds_week_day)
&& !window.static_data.year_data.timespans.some(month => month?.week?.length);

do_error_check("calendar", $event.detail.rerender);
}
Expand Down
505 changes: 0 additions & 505 deletions resources/js/calendar/calendar_inputs_edit.js

Large diffs are not rendered by default.

205 changes: 200 additions & 5 deletions resources/js/calendar/leap_days_collapsible.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,202 @@
export default () => ({
reordering: false,
import CollapsibleComponent from "./collapsible_component.js";
import { ordinal_suffix_of } from "./calendar_functions.js";

class LeapDaysCollapsible extends CollapsibleComponent {

name = "";
type = "";
deleting = -1;

interval_wide_regex = /[ `~@#$%^&*()_|\-=?;:'".<>\{\}\[\]\\\/A-Za-z]/g;
interval_internal_regex = /^\+*\!*[1-9]+[0-9]{0,}$/;
interval_numbers_regex = /([1-9]+[0-9]{0,})/;

leap_days = [];
weekdays = [];
timespans = [];

loads = {
"leap_days": "year_data.leap_days",
"weekdays": "year_data.global_week",
"timespans": "year_data.timespans"
}

setters = {
"leap_days": "year_data.leap_days"
}

addLeapDay(){
this.leap_days.push({
'name': this.name || `New ${this.type? this.type + " " : ''}leap day`,
'intercalary': this.type === 'intercalary',
'timespan': 0,
'adds_week_day': false,
'day': 0,
'week_day': '',
'interval': '1',
'offset': 0,
'not_numbered': false,
})
this.name = "";
}

removeLeapDay(index){
this.leap_days.splice(index, 1);
}

getLeapdayValidWeekdays(leapDay){
return this.timespans[leapDay.timespan]?.week?.length
? this.timespans[leapDay.timespan].week
: this.weekdays;
}

getLeapdayValidDays(leapDay){
return this.timespans[leapDay.timespan].length;
}

validateLeapDayInterval(leapDay, interval) {

interval = interval.replace(/,\s*$/, "");

if (interval === "0") {
// TODO: Add proper error messaging to outer components, and prevent re-render
// `${leapDay.name}'s interval is 0, please enter a positive number.`
return;
}

let invalid = this.interval_wide_regex.test(interval);

if(invalid) {
// TODO: Add proper error messaging to outer components, and prevent re-render
// `${leapDay.name} has an invalid interval formula.`
return;
}

let values = interval.split(',');

for(let value of values){
if (!this.interval_internal_regex.test(value)) {
invalid = true;
break;
}
}

if(invalid) {
// TODO: Add proper error messaging to outer components, and prevent re-render
// `${leapDay.name} has an invalid interval formula. Plus before exclamation point.` : '');
return;
}

let unsorted = [];

for (let value of values) {
unsorted.push(Number(value.match(this.interval_numbers_regex)[0]));
}

let sorted = unsorted.slice(0).sort((a, b) => {
if (a < b) return -1;
if (a > b) return 1;
return 0;
}).reverse();

let result = [];

for (let value of sorted) {
let index = unsorted.indexOf(value);
result.push(values[index]);
}

leapDay.interval = result.join(',');

}

getLeapDayIntervalText(leapDay) {

let values = leapDay.interval.split(',').reverse();
let sorted = [];

let numbers_regex = /([1-9]+[0-9]*)/;

for (let i = 0; i < values.length; i++) {
sorted.push(Number(values[i].match(numbers_regex)[0]));
}

let text = ["This leap day will appear every"];

let timespan_interval = this.timespans[leapDay.timespan].interval;
let timespan_offset = timespan_interval === 1 ? 0 : this.timespans[leapDay.timespan].offset;

let year_offset = timespan_offset % timespan_interval;

for (let i = 0; i < values.length; i++) {

text[i] ??= "";

let leap_interval = sorted[i];
let leap_offset = leapDay.offset;

let original_offset = ((leap_interval + leap_offset) % leap_interval);
let total_offset = original_offset === 0 ?sorted[i] : original_offset;

total_offset = (total_offset * timespan_interval) + timespan_offset;

if (i === 0 && sorted[i] === 1) {

if (timespan_interval === 1) {
text[i] += " year"
} else {
text[i] += ` ${ordinal_suffix_of(timespan_interval * sorted[i])} year (leaping month)`;
}

} else if (i === 0) {

if (this.timespans[leapDay.timespan].interval === 1) {
text[i] += ` ${ordinal_suffix_of(sorted[i])} year`;
} else {
text[i] += ` ${ordinal_suffix_of(timespan_interval * sorted[i])} ${this.timespans[leapDay.timespan].name}`;
}

if (values[i].indexOf('+') === -1 || year_offset !== 0) {
text[i] += ` (${this.calendar_settings.year_zero_exists && original_offset === 0 ? `year ${year_offset},` : "year"} ${total_offset}, ${total_offset + sorted[i] * timespan_interval}, ${total_offset + sorted[i] * 2 * timespan_interval}...)`;
}

}

if (i > 0 && sorted[i] > 1) {

if (values[i].indexOf('!') !== -1) {
if (timespan_interval === 1) {
text[i] += `but not every ${ordinal_suffix_of(sorted[i])} year`;
} else {
text[i] += `but not every ${ordinal_suffix_of(timespan_interval * sorted[i])} ${this.timespans[leapDay.timespan].name}`;
}

if (values[i].indexOf('+') === -1 || year_offset !== 0) {
text[i] += ` (${this.calendar_settings.year_zero_exists && original_offset === 0 ? `year ${year_offset},` : "year"} ${total_offset}, ${total_offset + sorted[i] * timespan_interval}, ${total_offset + sorted[i] * 2 * timespan_interval}...)`;
}

} else {

if (timespan_interval === 1) {
text[i] += `but also every ${ordinal_suffix_of(sorted[i])} year`;
} else {
text[i] += `but also every ${ordinal_suffix_of(timespan_interval * sorted[i])} ${this.timespans[leapDay.timespan].name}`;
}

if (values[i].indexOf('+') === -1 || year_offset !== 0) {
text[i] += ` (${this.calendar_settings.year_zero_exists && original_offset === 0 ? `year ${year_offset},` : "year"} ${total_offset}, ${total_offset + sorted[i] * timespan_interval}, ${total_offset + sorted[i] * 2 * timespan_interval}...)`;
}

}

}

}

return text;

load: function(static_data) {
//
}
})

}

export default () => new LeapDaysCollapsible();
5 changes: 2 additions & 3 deletions resources/js/calendar/weekdays_collapsible.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { do_error_check, populate_first_day_select } from "./calendar_inputs_edit";
import { set_up_view_values } from "./calendar_inputs_view";
import { populate_first_day_select } from "./calendar_inputs_edit";

import CollapsibleComponent from "./collapsible_component";

Expand Down Expand Up @@ -29,7 +28,7 @@ class WeekdaysCollapsible extends CollapsibleComponent {

loaded(static_data) {
this.deleting = -1;
this.show_custom_week_warning = static_data.year_data.timespans.some(timespan => timespan.week !== undefined)
this.show_custom_week_warning = static_data.year_data.timespans.some(timespan => timespan?.week?.length)
|| static_data.year_data.leap_days.some(leapDay => leapDay.adds_week_day);
}

Expand Down
Loading

0 comments on commit 12f61e4

Please sign in to comment.