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>
import { getRelativeString } from '@/models/Date'
import { storeToRefs } from 'pinia'
import { computed } from 'vue'
import { PhMapPin } from '@phosphor-icons/vue'
const { defaultDate, getFormattedDateTitle } = useCalendar()
const { defaultDate, getFormattedDateTitle, getRelativeString } = useCalendar()
const { selectedDate } = storeToRefs(useCalendar())
const mainDateTitle = computed(() => getFormattedDateTitle(selectedDate.value, true))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,168 +6,6 @@ export interface RPGDate {
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) {
// let newDay: number
// let newMonth: number

View File

@@ -1,5 +1,6 @@
import {
type RPGDate,
type RPGDateOrder,
} from '@/models/Date'
import { useLocalStorage, useUrlSearchParams } from '@vueuse/core'
import { defineStore, skipHydrate } from 'pinia'
@@ -284,6 +285,18 @@ export const useCalendar = defineStore('calendar', () => {
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
*
@@ -293,6 +306,9 @@ export const useCalendar = defineStore('calendar', () => {
currentConfig.value.viewType = viewType
}
/**
* FORMATTING
*/
/**
* Gets the formatted viewType title
*
@@ -331,6 +347,9 @@ export const useCalendar = defineStore('calendar', () => {
return `${getMonthName(date.month)} ${date.year}`
}
/**
* DATE JUMPS & SELECTION
*/
/**
* Jumps the calendar to the given date
*
@@ -357,10 +376,166 @@ export const useCalendar = defineStore('calendar', () => {
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() {
isAdvancedSearchOpen.value = true
numberOfDays = numberOfDays + dateToConvert.month * 1 // daysPerMonth
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 {
@@ -394,6 +569,11 @@ export const useCalendar = defineStore('calendar', () => {
getViewTypeTitle,
isCurrentScreenActive,
isAdvancedSearchOpen,
convertDateToDays,
getDifferenceInDays,
areDatesIdentical,
compareDates,
getRelativeString,
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 { defineStore } from 'pinia'
import { ref, watch, type Ref } from 'vue'
import { useCalendar } from './CalendarStore'
export const useCalendarEvents = defineStore('calendar-events', () => {
const { currentDate, currentConfig } = useCalendar()
const { currentDate, currentConfig, convertDateToDays, compareDates } = useCalendar()
const baseEvents = ref<CalendarEvent[]>([])
@@ -34,8 +34,8 @@ export const useCalendarEvents = defineStore('calendar-events', () => {
* @returns Whether the event should appear in the current view
*/
function shouldEventBeDisplayed(event: CalendarEvent): boolean {
const eventStartDateToDays = convertDateToDays(event.startDate)
const eventEndDateToDays: number = event.endDate ? convertDateToDays(event.endDate) : 0
// const eventStartDateToDays = convertDateToDays(event.startDate)
// const eventEndDateToDays: number = event.endDate ? convertDateToDays(event.endDate) : 0
const isEventOnCurrentScreen =
(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
// This is to allow leap events from appearing on the last 8 tiles
const firstDayOfCurrentMonth = convertDateToDays({
day: 1,
month: currentDate.currentMonth,
year: currentDate.currentYear
})
const lastDayOfCurrentMonth = firstDayOfCurrentMonth + daysPerMonth
const last8Tiles = lastDayOfCurrentMonth + 8
//
// This is not used for now
//
// const firstDayOfCurrentMonth = convertDateToDays({
// day: 1,
// month: currentDate.currentMonth,
// year: currentDate.currentYear
// })
// const lastDayOfCurrentMonth = firstDayOfCurrentMonth + daysPerMonth
// const last8Tiles = lastDayOfCurrentMonth + 8
const isEventOnNext8Tiles =
(eventStartDateToDays <= last8Tiles && eventStartDateToDays >= lastDayOfCurrentMonth) ||
(Boolean(event.endDate) &&
eventEndDateToDays <= last8Tiles &&
eventEndDateToDays >= lastDayOfCurrentMonth)
// const isEventOnNext8Tiles =
// (eventStartDateToDays <= last8Tiles && eventStartDateToDays >= lastDayOfCurrentMonth) ||
// (Boolean(event.endDate) &&
// eventEndDateToDays <= last8Tiles &&
// eventEndDateToDays >= lastDayOfCurrentMonth)
switch (currentConfig.viewType) {
case 'month':
return isEventOnCurrentScreen || isEventOnNext8Tiles
return isEventOnCurrentScreen!
case 'year':
return event.startDate.year === currentDate.currentYear