This broke most things tbh, the date functions need to be reworked to account for differently formatted calendars (how idk). This would fix most issues that stem from it in other screens

This commit is contained in:
Alexis
2024-05-18 20:56:38 +02:00
parent 73e4b0e3d7
commit 13b8be9399
12 changed files with 228 additions and 197 deletions

View File

@@ -1,11 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getRelativeString } from '@/models/Date'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { computed } from 'vue' import { computed } from 'vue'
import { PhMapPin } from '@phosphor-icons/vue' import { PhMapPin } from '@phosphor-icons/vue'
const { defaultDate, getFormattedDateTitle } = useCalendar() const { defaultDate, getFormattedDateTitle, getRelativeString } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar()) const { selectedDate } = storeToRefs(useCalendar())
const mainDateTitle = computed(() => getFormattedDateTitle(selectedDate.value, true)) const mainDateTitle = computed(() => getFormattedDateTitle(selectedDate.value, true))

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue' import { ref } from 'vue'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { areDatesIdentical, type RPGDate } from '@/models/Date' import type { RPGDate } from '@/models/Date'
import type { CalendarEvent } from '~/models/CalendarEvent' import type { CalendarEvent } from '~/models/CalendarEvent'
const props = defineProps<{ const props = defineProps<{
@@ -9,6 +9,8 @@ const props = defineProps<{
tileDate: RPGDate tileDate: RPGDate
}>() }>()
const { areDatesIdentical } = useCalendar()
const spansMultipleDays = Boolean(props.event.startDate && props.event.endDate) const spansMultipleDays = Boolean(props.event.startDate && props.event.endDate)
const isStartEvent = spansMultipleDays && areDatesIdentical(props.tileDate, props.event.startDate) const isStartEvent = spansMultipleDays && areDatesIdentical(props.tileDate, props.event.startDate)

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getRelativeString, type RPGDate } from '@/models/Date' import type { RPGDate } from '@/models/Date'
import type { CalendarEvent } from '@/models/CalendarEvent' import type { CalendarEvent } from '@/models/CalendarEvent'
import { useCalendar } from '@/stores/CalendarStore' import { useCalendar } from '@/stores/CalendarStore'
import { useCalendarEvents } from '@/stores/EventStore' import { useCalendarEvents } from '@/stores/EventStore'
@@ -27,6 +27,8 @@ const emit = defineEmits<{
(e: 'query:close-popover'): void (e: 'query:close-popover'): void
}>() }>()
const { getRelativeString } = useCalendar()
const dateDifference: string = getRelativeString(defaultDate, props.event.startDate) const dateDifference: string = getRelativeString(defaultDate, props.event.startDate)
const dateDuration: string | null = props.event.endDate const dateDuration: string | null = props.event.endDate
? getRelativeString(props.event.startDate, props.event.endDate, 'compact') ? getRelativeString(props.event.startDate, props.event.endDate, 'compact')

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { daysPerMonth, monthsPerYear, type RPGDate } from '@/models/Date' import { type RPGDate } from '@/models/Date'
import { useCalendar } from '@/stores/CalendarStore' import { useCalendar } from '@/stores/CalendarStore'
import { useCalendarEvents } from '@/stores/EventStore' import { useCalendarEvents } from '@/stores/EventStore'
@@ -10,6 +10,11 @@ const { getRelativeEventFromDate } = useCalendarEvents()
function handleGotoPreviousEventPage(position: 'next' | 'prev' = 'next') { function handleGotoPreviousEventPage(position: 'next' | 'prev' = 'next') {
let fromDate: RPGDate let fromDate: RPGDate
// To modify, obviously
const daysPerMonth = 30
const monthsPerYear = 10
const toDay = position === 'next' ? daysPerMonth : 1 const toDay = position === 'next' ? daysPerMonth : 1
const toMonth = position === 'next' ? monthsPerYear : 0 const toMonth = position === 'next' ? monthsPerYear : 0

View File

@@ -3,9 +3,7 @@ import { useCalendar } from '@/stores/CalendarStore'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { computed } from 'vue' import { computed } from 'vue'
import { areDatesIdentical } from '@/models/Date' const { defaultDate, areDatesIdentical } = useCalendar()
const { defaultDate } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar()) const { selectedDate } = storeToRefs(useCalendar())
const { jumpToDefaultDate, getFormattedDateTitle } = useCalendar() const { jumpToDefaultDate, getFormattedDateTitle } = useCalendar()

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { getRelativeString, type RPGDate } from '@/models/Date' import type { RPGDate } from '@/models/Date'
import type { CalendarEvent } from '@/models/CalendarEvent' import type { CalendarEvent } from '@/models/CalendarEvent'
import { useCalendar } from '@/stores/CalendarStore' import { useCalendar } from '@/stores/CalendarStore'
@@ -13,6 +13,8 @@ defineEmits<{
(e: 'query:date-jump', payload: RPGDate): void (e: 'query:date-jump', payload: RPGDate): void
}>() }>()
const { getRelativeString } = useCalendar()
const { defaultDate, getFormattedDateTitle } = useCalendar() const { defaultDate, getFormattedDateTitle } = useCalendar()
const dateDifference: string = getRelativeString(defaultDate, props.event.startDate) const dateDifference: string = getRelativeString(defaultDate, props.event.startDate)

View File

@@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { isCharacter, type Character } from '@/models/Characters' import { isCharacter, type Character } from '@/models/Characters'
import { compareDates, type RPGDate, type RPGDateOrder } from '@/models/Date' import type { RPGDate, RPGDateOrder } from '@/models/Date'
import { isCalendarEvent, type CalendarEvent } from '~/models/CalendarEvent'
import { useCalendar } from '@/stores/CalendarStore' import { useCalendar } from '@/stores/CalendarStore'
import { computed } from 'vue' import { computed } from 'vue'
import { isCalendarEvent, type CalendarEvent } from '~/models/CalendarEvent'
import type { SearchMode } from '../../SearchMode' import type { SearchMode } from '../../SearchMode'
import CharacterCallout from './CharacterCallout.vue' import CharacterCallout from './CharacterCallout.vue'
@@ -20,7 +20,7 @@ const props = defineProps<{
const emit = defineEmits(['jumpedToDate']) const emit = defineEmits(['jumpedToDate'])
const { jumpToDate } = useCalendar() const { jumpToDate, compareDates } = useCalendar()
function handleJumpToDate(date?: RPGDate) { function handleJumpToDate(date?: RPGDate) {
if (!date) return if (!date) return

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { areDatesIdentical, type RPGDate } from '@/models/Date' import type { RPGDate } from '@/models/Date'
import { useCalendar } from '@/stores/CalendarStore' import { useCalendar } from '@/stores/CalendarStore'
import { useCalendarEvents } from '@/stores/EventStore' import { useCalendarEvents } from '@/stores/EventStore'
import { useElementBounding } from '@vueuse/core' import { useElementBounding } from '@vueuse/core'
@@ -17,7 +17,7 @@ const props = defineProps<{
const calendarTile = ref() const calendarTile = ref()
const calendarEventsList = ref() const calendarEventsList = ref()
const { defaultDate, selectDate } = useCalendar() const { defaultDate, selectDate, areDatesIdentical } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar()) const { selectedDate } = storeToRefs(useCalendar())
const { currentEvents } = storeToRefs(useCalendarEvents()) const { currentEvents } = storeToRefs(useCalendarEvents())

View File

@@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { areDatesIdentical, type RPGDate } from '@/models/Date' import type { RPGDate } from '@/models/Date'
import { useCalendar } from '@/stores/CalendarStore' import { useCalendar } from '@/stores/CalendarStore'
import { useCalendarEvents } from '@/stores/EventStore' import { useCalendarEvents } from '@/stores/EventStore'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
@@ -14,6 +14,8 @@ const props = defineProps<{
dayNumber: number dayNumber: number
}>() }>()
const { areDatesIdentical } = useCalendar()
const tileDate: ComputedRef<RPGDate> = computed(() => { const tileDate: ComputedRef<RPGDate> = computed(() => {
return { return {
day: props.dayNumber, day: props.dayNumber,

View File

@@ -6,168 +6,6 @@ export interface RPGDate {
export type RPGDateOrder = 'asc' | 'desc' export type RPGDateOrder = 'asc' | 'desc'
export const monthsPerYear: number = 10
export const daysPerYear: number = 320
export const daysPerMonth: number = 32
export const daysPerWeek: number = 6
/**
* Check whether two dates are identical
*
* @param date1 First date
* @param date2 Second date
* @returns True if the dates are identical
*/
export function areDatesIdentical(date1: RPGDate, date2: RPGDate): boolean {
return convertDateToDays({ ...date1 }) === convertDateToDays({ ...date2 })
}
/**
* Compare dates
*
* @param date1 First date
* @param date2 Second date
* @returns 1 means the first date comes before the second, -1 means the second comes before the first, and 0 if they're identical
*/
export function compareDates(a: RPGDate, b: RPGDate, order: RPGDateOrder = 'desc'): number {
// Reverses the order if specified
const orderFactor: number = order === 'desc' ? 1 : -1
// Compare years
if (a.year < b.year) return -1 * orderFactor
if (a.year > b.year) return 1 * orderFactor
// Compare months
if (a.month < b.month) return -1 * orderFactor
if (a.month > b.month) return 1 * orderFactor
// Compare days
if (a.day < b.day) return -1 * orderFactor
if (a.day > b.day) return 1 * orderFactor
return 0
}
/**
* Converts a RPGDate to its equivalent in days
*
* @todo Handle negative dates
* @param dateToConvert The date object
* @returns How many days does it represent
*/
export function convertDateToDays(dateToConvert: RPGDate): number {
let numberOfDays: number = dateToConvert.day
numberOfDays = numberOfDays + dateToConvert.month * daysPerMonth
numberOfDays = numberOfDays + dateToConvert.year * daysPerYear
return numberOfDays
}
/**
* From two dates, get the difference in days between them
* @param baseDate The base date
* @param relativeDate The year to compare it to
* @returns The number of days separating the two dates (both positive and negative numbers)
*/
export function getDifferenceInDays(baseDate: RPGDate, relativeDate: RPGDate): number {
return convertDateToDays(relativeDate) - convertDateToDays(baseDate)
}
/**
* From two dates, gives information on how many years, months and days it has been / will be between them
*
* @param baseDate The base date
* @param relativeDate The year to compare it to
* @returns A string with info on how the relative date differs to the base date
*/
export function getRelativeString(
baseDate: RPGDate,
relativeDate: RPGDate,
formatting: 'compact' | 'complex' = 'complex'
): string {
const differenceInDays: number = getDifferenceInDays(baseDate, relativeDate)
let output: string = ''
let direction: 'past' | 'present' | 'future' = 'present'
let directionPrefix: string = ''
// Check whether it's a past or future date
if (differenceInDays > 0) {
direction = 'future'
} else if (differenceInDays < 0) {
direction = 'past'
}
if (formatting === 'complex') {
// Handle if it's the same date
if (direction === 'present') {
return "Aujourd'hui"
}
if (differenceInDays === -2) {
return 'Avant-hier'
}
if (differenceInDays === -1) {
return 'Hier'
}
if (differenceInDays === 1) {
return 'Demain'
}
if (differenceInDays === 2) {
return 'Après-demain'
}
// Get relevant prefix for the string
if (direction === 'future') {
directionPrefix = 'Dans '
} else if (direction === 'past') {
directionPrefix = 'Il y a '
}
output += directionPrefix
}
const yearPackets: number = Math.abs(Math.trunc(differenceInDays / daysPerYear))
const monthPackets: number = Math.abs(Math.trunc(differenceInDays / daysPerMonth) % monthsPerYear)
const remainingDays: number =
Math.abs(differenceInDays) - (yearPackets * daysPerYear + monthPackets * daysPerMonth)
// Assign year part
if (yearPackets) {
if (yearPackets === 1) {
output += `${yearPackets} an`
} else {
output += `${yearPackets} ans`
}
}
// Assign month part
if (monthPackets) {
// If there was a year packet(s), separate from them
if (yearPackets) {
output += ','
}
output += ` ${monthPackets} mois`
}
// Assign day part
if (remainingDays) {
// If there was a year OR month packet(s), separate from them
if (yearPackets || monthPackets) {
output += ' et'
}
if (remainingDays === 1) {
output += ` ${remainingDays} jour`
} else {
output += ` ${remainingDays} jours`
}
}
return output
}
// export function getRelativeDate(baseDate: RPGDate, relativeDate: RPGDate) { // export function getRelativeDate(baseDate: RPGDate, relativeDate: RPGDate) {
// let newDay: number // let newDay: number
// let newMonth: number // let newMonth: number

View File

@@ -1,5 +1,6 @@
import { import {
type RPGDate, type RPGDate,
type RPGDateOrder,
} from '@/models/Date' } from '@/models/Date'
import { useLocalStorage, useUrlSearchParams } from '@vueuse/core' import { useLocalStorage, useUrlSearchParams } from '@vueuse/core'
import { defineStore, skipHydrate } from 'pinia' import { defineStore, skipHydrate } from 'pinia'
@@ -284,6 +285,18 @@ export const useCalendar = defineStore('calendar', () => {
return '' return ''
} }
/**
* State for advanced search modal
*/
const isAdvancedSearchOpen: Ref<boolean> = ref<boolean>(false)
/**
* Opens the search modal
*/
function revealAdvancedSearch() {
isAdvancedSearchOpen.value = true
}
/** /**
* Switches the active viewType * Switches the active viewType
* *
@@ -293,6 +306,9 @@ export const useCalendar = defineStore('calendar', () => {
currentConfig.value.viewType = viewType currentConfig.value.viewType = viewType
} }
/**
* FORMATTING
*/
/** /**
* Gets the formatted viewType title * Gets the formatted viewType title
* *
@@ -331,6 +347,9 @@ export const useCalendar = defineStore('calendar', () => {
return `${getMonthName(date.month)} ${date.year}` return `${getMonthName(date.month)} ${date.year}`
} }
/**
* DATE JUMPS & SELECTION
*/
/** /**
* Jumps the calendar to the given date * Jumps the calendar to the given date
* *
@@ -357,10 +376,166 @@ export const useCalendar = defineStore('calendar', () => {
selectedDate.value = date selectedDate.value = date
} }
const isAdvancedSearchOpen: Ref<boolean> = ref<boolean>(false) /**
* DATE OPERATIONS
*
* Used to convert dates, sort them and compare them
*/
/**
* Converts a RPGDate to its equivalent in days
*
* @todo Handle negative dates
* @param dateToConvert The date object
* @returns How many days does it represent
*/
function convertDateToDays(dateToConvert: RPGDate): number {
let numberOfDays: number = dateToConvert.day
function revealAdvancedSearch() { numberOfDays = numberOfDays + dateToConvert.month * 1 // daysPerMonth
isAdvancedSearchOpen.value = true numberOfDays = numberOfDays + dateToConvert.year * daysPerYear.value
return numberOfDays
}
/**
* From two dates, get the difference in days between them
* @param baseDate The base date
* @param relativeDate The year to compare it to
* @returns The number of days separating the two dates (both positive and negative numbers)
*/
function getDifferenceInDays(baseDate: RPGDate, relativeDate: RPGDate): number {
return convertDateToDays(relativeDate) - convertDateToDays(baseDate)
}
/**
* Check whether two dates are identical
*
* @param date1 First date
* @param date2 Second date
* @returns True if the dates are identical
*/
function areDatesIdentical(date1: RPGDate, date2: RPGDate): boolean {
return getDifferenceInDays({ ...date1 }, { ...date2 }) === 0
}
/**
* Compare dates (used for array sorting)
*
* @param date1 First date
* @param date2 Second date
* @returns 1 means the first date comes before the second, -1 means the second comes before the first, and 0 if they're identical
*/
function compareDates(a: RPGDate, b: RPGDate, order: RPGDateOrder = 'desc'): number {
// Reverses the order if specified
const orderFactor: number = order === 'desc' ? 1 : -1
// Compare years
if (a.year < b.year) return -1 * orderFactor
if (a.year > b.year) return 1 * orderFactor
// Compare months
if (a.month < b.month) return -1 * orderFactor
if (a.month > b.month) return 1 * orderFactor
// Compare days
if (a.day < b.day) return -1 * orderFactor
if (a.day > b.day) return 1 * orderFactor
return 0
}
/**
* From two dates, gives information on how many years, months and days it has been / will be between them
*
* @param baseDate The base date
* @param relativeDate The year to compare it to
* @returns A string with info on how the relative date differs to the base date
*/
function getRelativeString(
baseDate: RPGDate,
relativeDate: RPGDate,
formatting: 'compact' | 'complex' = 'complex'
): string {
const differenceInDays: number = getDifferenceInDays(baseDate, relativeDate)
let output: string = ''
let direction: 'past' | 'present' | 'future' = 'present'
let directionPrefix: string = ''
// Check whether it's a past or future date
if (differenceInDays > 0) {
direction = 'future'
} else if (differenceInDays < 0) {
direction = 'past'
}
if (formatting === 'complex') {
// Handle if it's the same date
if (direction === 'present') {
return "Aujourd'hui"
}
if (differenceInDays === -2) {
return 'Avant-hier'
}
if (differenceInDays === -1) {
return 'Hier'
}
if (differenceInDays === 1) {
return 'Demain'
}
if (differenceInDays === 2) {
return 'Après-demain'
}
// Get relevant prefix for the string
if (direction === 'future') {
directionPrefix = 'Dans '
} else if (direction === 'past') {
directionPrefix = 'Il y a '
}
output += directionPrefix
}
const yearPackets: number = Math.abs(Math.trunc(differenceInDays / daysPerYear.value))
const monthPackets: number = Math.abs(Math.trunc(differenceInDays / 1) % 1) // daysPerMonth, monthsPerYear
const remainingDays: number =
Math.abs(differenceInDays) - (yearPackets * daysPerYear.value + monthPackets * 1) // daysPerMonth
// Assign year part
if (yearPackets) {
if (yearPackets === 1) {
output += `${yearPackets} an`
} else {
output += `${yearPackets} ans`
}
}
// Assign month part
if (monthPackets) {
// If there was a year packet(s), separate from them
if (yearPackets) {
output += ','
}
output += ` ${monthPackets} mois`
}
// Assign day part
if (remainingDays) {
// If there was a year OR month packet(s), separate from them
if (yearPackets || monthPackets) {
output += ' et'
}
if (remainingDays === 1) {
output += ` ${remainingDays} jour`
} else {
output += ` ${remainingDays} jours`
}
}
return output
} }
return { return {
@@ -394,6 +569,11 @@ export const useCalendar = defineStore('calendar', () => {
getViewTypeTitle, getViewTypeTitle,
isCurrentScreenActive, isCurrentScreenActive,
isAdvancedSearchOpen, isAdvancedSearchOpen,
convertDateToDays,
getDifferenceInDays,
areDatesIdentical,
compareDates,
getRelativeString,
revealAdvancedSearch revealAdvancedSearch
} }
}) })

View File

@@ -1,11 +1,11 @@
import { compareDates, convertDateToDays, daysPerMonth, type RPGDate } from '@/models/Date' import type { RPGDate } from '@/models/Date'
import type { CalendarEvent } from '@/models/CalendarEvent' import type { CalendarEvent } from '@/models/CalendarEvent'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, watch, type Ref } from 'vue' import { ref, watch, type Ref } from 'vue'
import { useCalendar } from './CalendarStore' import { useCalendar } from './CalendarStore'
export const useCalendarEvents = defineStore('calendar-events', () => { export const useCalendarEvents = defineStore('calendar-events', () => {
const { currentDate, currentConfig } = useCalendar() const { currentDate, currentConfig, convertDateToDays, compareDates } = useCalendar()
const baseEvents = ref<CalendarEvent[]>([]) const baseEvents = ref<CalendarEvent[]>([])
@@ -34,8 +34,8 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
* @returns Whether the event should appear in the current view * @returns Whether the event should appear in the current view
*/ */
function shouldEventBeDisplayed(event: CalendarEvent): boolean { function shouldEventBeDisplayed(event: CalendarEvent): boolean {
const eventStartDateToDays = convertDateToDays(event.startDate) // const eventStartDateToDays = convertDateToDays(event.startDate)
const eventEndDateToDays: number = event.endDate ? convertDateToDays(event.endDate) : 0 // const eventEndDateToDays: number = event.endDate ? convertDateToDays(event.endDate) : 0
const isEventOnCurrentScreen = const isEventOnCurrentScreen =
(event.startDate.year === currentDate.currentYear && (event.startDate.year === currentDate.currentYear &&
@@ -46,23 +46,26 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
// Check whether the event is on the last 8 tiles // Check whether the event is on the last 8 tiles
// This is to allow leap events from appearing on the last 8 tiles // This is to allow leap events from appearing on the last 8 tiles
const firstDayOfCurrentMonth = convertDateToDays({ //
day: 1, // This is not used for now
month: currentDate.currentMonth, //
year: currentDate.currentYear // const firstDayOfCurrentMonth = convertDateToDays({
}) // day: 1,
const lastDayOfCurrentMonth = firstDayOfCurrentMonth + daysPerMonth // month: currentDate.currentMonth,
const last8Tiles = lastDayOfCurrentMonth + 8 // year: currentDate.currentYear
// })
// const lastDayOfCurrentMonth = firstDayOfCurrentMonth + daysPerMonth
// const last8Tiles = lastDayOfCurrentMonth + 8
const isEventOnNext8Tiles = // const isEventOnNext8Tiles =
(eventStartDateToDays <= last8Tiles && eventStartDateToDays >= lastDayOfCurrentMonth) || // (eventStartDateToDays <= last8Tiles && eventStartDateToDays >= lastDayOfCurrentMonth) ||
(Boolean(event.endDate) && // (Boolean(event.endDate) &&
eventEndDateToDays <= last8Tiles && // eventEndDateToDays <= last8Tiles &&
eventEndDateToDays >= lastDayOfCurrentMonth) // eventEndDateToDays >= lastDayOfCurrentMonth)
switch (currentConfig.viewType) { switch (currentConfig.viewType) {
case 'month': case 'month':
return isEventOnCurrentScreen || isEventOnNext8Tiles return isEventOnCurrentScreen!
case 'year': case 'year':
return event.startDate.year === currentDate.currentYear return event.startDate.year === currentDate.currentYear