Migrate to dayjs and Astro 4.0

Dieser Commit ist enthalten in:
Chaoscaot 2023-12-07 00:17:32 +01:00
Ursprung 505ee26622
Commit 311856415e
24 geänderte Dateien mit 731 neuen und 980 gelöschten Zeilen

Datei anzeigen

@ -22,6 +22,7 @@ export default function configureI18n(): AstroIntegration {
}
await rename(`${cutPrefix(oldPath)}index.html`, `${cutPrefix(newPath)}index.${locale}.html`)
logger.info(`Renamed ${oldPath} to ${newPath}`)
}
}

Datei anzeigen

@ -11,5 +11,5 @@ export default defineConfig({
},
compressHTML: true,
integrations: [svelte(), tailwind(), configureI18n()],
vite: {},
vite: {}
});

Datei anzeigen

@ -15,8 +15,8 @@
},
"devDependencies": {
"@astrojs/prefetch": "^0.4.1",
"@astrojs/svelte": "^4.0.4",
"@astrojs/tailwind": "^5.0.2",
"@astrojs/svelte": "^5.0.0",
"@astrojs/tailwind": "^5.0.3",
"@astropub/icons": "^0.2.0",
"@types/color": "^3.0.6",
"@types/crypto-js": "^4.2.1",
@ -27,22 +27,24 @@
"sass": "^1.69.5",
"svelte": "^4.2.8",
"tailwind-merge": "^2.0.0",
"tailwindcss": "^3.3.5"
"tailwindcss": "^3.3.5",
"typescript": "^5.3.2"
},
"dependencies": {
"@codemirror/lang-json": "^6.0.1",
"@ddietr/codemirror-themes": "^1.4.2",
"astro": "^3.6.4",
"astro": "^4.0.2",
"astro-i18n": "^2.1.18",
"chart.js": "^4.4.0",
"chartjs-adapter-dayjs-4": "^1.0.4",
"chartjs-adapter-moment": "^1.0.1",
"color": "^4.2.3",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
"easymde": "^2.18.0",
"flowbite": "^1.8.1",
"flowbite-svelte": "^0.44.20",
"flowbite-svelte-icons": "^0.4.5",
"moment": "^2.29.4",
"sharp": "^0.32.6",
"svelte-awesome": "^3.2.1",
"svelte-codemirror-editor": "^1.2.0",

Datei-Diff unterdrückt, da er zu groß ist Diff laden

Datei anzeigen

@ -1,20 +1,6 @@
<script lang="ts">
import {astroI18n, t} from "astro-i18n"
import {l} from "../util/util.ts"
import {dataRepo, schemRepo, tokenStore} from "./repo/repo.ts";
import moment from "moment";
import {
CheckSolid,
ChevronDoubleRightOutline,
FileOutline,
FolderOutline, HomeOutline,
InfoCircleOutline,
XCircleOutline
} from "flowbite-svelte-icons";
import {Breadcrumb, BreadcrumbItem, Modal, Tooltip} from "flowbite-svelte";
import SchematicInfo from "./dashboard/SchematicInfo.svelte";
import SchematicListTile from "./dashboard/SchematicListTile.svelte";
import UploadModal from "./dashboard/UploadModal.svelte";
import {t} from "astro-i18n"
import {dataRepo, schemRepo} from "./repo/repo";
import SchematicList from "./dashboard/SchematicList.svelte";
import UserInfo from "./dashboard/UserInfo.svelte";

Datei anzeigen

@ -12,10 +12,10 @@
Title
} from "chart.js"
import type {FightStats} from "./types/stats.ts"
import 'chartjs-adapter-moment'
import 'chartjs-adapter-dayjs-4'
export let data: FightStats;
let chart;
let chart: Chart;
let canvas: HTMLCanvasElement;
onMount(async () => {
@ -25,13 +25,7 @@
}
const colors = ["#abfa91", "#279900", "#00ffbe", "#9297fb", "#050b9d", "#b60fff", "#8dddfc", "#0880ad", "#41ff00", "#039973", "#96fce2", "#0009ff", "#7501a4", "#e2a2fb", "#00b9ff"];
const map = new Map<string, {x: Date, y: number}[]>()
for (const {date, count, gamemode} of data) {
if (!map.has(gamemode)) {
map.set(gamemode, [])
}
map.get(gamemode)!!.push({x: new Date(date), y: count})
}
const map = Map.groupBy(data, entry => entry.gamemode);
chart = new Chart(
canvas,

Datei anzeigen

@ -6,5 +6,4 @@ import {server} from "./stores/stores.ts";
{#await $server}
{:then data}
{data.players.online}
{:catch error}
{/await}

Datei anzeigen

@ -2,19 +2,22 @@
import type {ExtendedEvent} from "../../../types/event.js";
import {Button, Heading, Input, Label, Modal, Range, Select, Toast, Toggle} from "flowbite-svelte";
import {schemTypes} from "../../../stores/stores.js";
import moment from "moment/moment.js";
import * as dayjs from "dayjs";
import * as utc from "dayjs/plugin/utc"
import type {UpdateEvent} from "../../../repo/event.js";
import {eventRepo} from "../../../repo/repo.js";
import ErrorModal from "../../components/ErrorModal.svelte";
import {replace} from "svelte-spa-router";
import {CheckCircleOutline} from "flowbite-svelte-icons";
dayjs.extend(utc);
export let data: ExtendedEvent;
let event = data.event;
let name = event.name;
let deadline = moment(event.deadline).utc(true).toISOString().slice(0, -1);
let start = moment(event.start).utc(true).toISOString().slice(0, -1);
let end = moment(event.end).utc(true).toISOString().slice(0, -1);
let deadline = dayjs(event.deadline).utc(true).toISOString().slice(0, -1);
let start = dayjs(event.start).utc(true).toISOString().slice(0, -1);
let end = dayjs(event.end).utc(true).toISOString().slice(0, -1);
let member = event.maxTeamMembers;
let schemType = event.schemType;
let publicOnly = event.publicSchemsOnly;
@ -24,9 +27,9 @@
let error: Error = undefined;
let deleteOpen = false;
$: deadlineDate = moment(deadline);
$: startDate = moment(start);
$: endDate = moment(end);
$: deadlineDate = dayjs(deadline);
$: startDate = dayjs(start);
$: endDate = dayjs(end);
$: selectTypes = [{
value: null,
name: "None"
@ -38,9 +41,9 @@
})];
$: changed = name !== event.name ||
deadlineDate.diff(moment(event.deadline)) !== 0 ||
startDate.diff(moment(event.start)) !== 0 ||
endDate.diff(moment(event.end)) !== 0 ||
deadlineDate.diff(dayjs(event.deadline)) !== 0 ||
startDate.diff(dayjs(event.start)) !== 0 ||
endDate.diff(dayjs(event.end)) !== 0 ||
member !== event.maxTeamMembers ||
schemType != event.schemType ||
publicOnly !== event.publicSchemsOnly ||

Datei anzeigen

@ -21,7 +21,9 @@
import {groups, players} from "../../../stores/stores.js";
import TypeAheadSearch from "../../components/TypeAheadSearch.svelte";
import type {UpdateFight} from "../../../repo/fight.js";
import moment from "moment";
import * as dayjs from "dayjs";
import * as duration from "dayjs/plugin/duration"
dayjs.extend(duration)
export let data: ExtendedEvent;
@ -133,11 +135,11 @@
groupChangeOpen = false;
}
$: minTime = moment(Math.min(...fights.map(fight => fight.start))).utc(true);
$: minTime = dayjs(Math.min(...fights.map(fight => fight.start))).utc(true);
let changeTimeOpen = false;
let changedTime = moment(Math.min(...fights.map(fight => fight.start)))?.utc(true)?.toISOString()?.slice(0, -1);
let changedTime = dayjs(Math.min(...fights.map(fight => fight.start)))?.utc(true)?.toISOString()?.slice(0, -1);
$: deltaTime = moment.duration(moment(changedTime).utc(true).diff(minTime))
$: deltaTime = dayjs.duration(dayjs(changedTime).utc(true).diff(minTime))
async function updateStartTime() {
for (const fight of selectedFights) {
@ -148,7 +150,7 @@
map: null,
redTeam: null,
spielmodus: null,
start: moment(fight.start).add(deltaTime.asMilliseconds(), 'millisecond')
start: dayjs(fight.start).add(deltaTime.asMilliseconds(), 'millisecond')
};
await $fightRepo.updateFight(fight.id, f);
}

Datei anzeigen

@ -6,7 +6,7 @@
import type {CreateFight} from "../../../../repo/fight.ts";
import ErrorModal from "../../../components/ErrorModal.svelte";
import {createEventDispatcher} from "svelte";
import moment from "moment";
import * as dayjs from "dayjs";
let dispatch = createEventDispatcher();
@ -37,7 +37,7 @@
spielmodus: gamemode,
blueTeam: parseInt(blueTeam),
redTeam: parseInt(redTeam),
start: moment(start),
start: dayjs(start),
map,
kampfleiter: parseInt(kampfleiter),
group,

Datei anzeigen

@ -1,14 +1,15 @@
<script lang="ts">
import {Button, Input, Label, Modal, Select} from "flowbite-svelte";
import moment from "moment";
import {gamemodes, groups, maps, players} from "../../../../stores/stores.js";
import type {EventFight, ExtendedEvent} from "../../../../types/event.js";
import TypeAheadSearch from "../../../components/TypeAheadSearch.svelte";
import FightEditPart from "../../../components/FightEditPart.svelte";
import type {UpdateFight} from "../../../../repo/fight.js";
import {fightRepo} from "../../../../repo/repo.js";
import ErrorModal from "../../../components/ErrorModal.svelte";
import {createEventDispatcher} from "svelte";
import * as dayjs from "dayjs";
import * as utc from "dayjs/plugin/utc";
dayjs.extend(utc);
export let fight: EventFight;
export let data: ExtendedEvent;
@ -16,7 +17,7 @@
let redTeam = fight.redTeam.id.toString();
let blueTeam = fight.blueTeam.id.toString();
let start = moment(fight.start).utc(true).toISOString().slice(0, -1);
let start = dayjs(fight.start).utc(true).toISOString().slice(0, -1);
let kampfleiter = fight.kampfleiter.id.toString();
let gamemode = fight.spielmodus
let map = fight.map;
@ -29,7 +30,7 @@
let dispatch = createEventDispatcher();
function save() {
const update: UpdateFight = {
blueTeam: parseInt(blueTeam), group: group === "" ? null : group, kampfleiter: parseInt(kampfleiter), map: map, redTeam: parseInt(redTeam), spielmodus: gamemode, start: moment(start)
blueTeam: parseInt(blueTeam), group: group === "" ? null : group, kampfleiter: parseInt(kampfleiter), map: map, redTeam: parseInt(redTeam), spielmodus: gamemode, start: dayjs(start)
}
$fightRepo.updateFight(fight.id, update)

Datei anzeigen

@ -3,12 +3,12 @@
import TeamChip from "./TeamChip.svelte";
import type {Team} from "../../../types/team.js";
import DragAcceptor from "./DragAcceptor.svelte";
import moment from "moment";
import {Button, Input, Label, Modal, Range, Select} from "flowbite-svelte";
import {gamemodes, maps} from "../../../stores/stores.js";
import {PlusSolid} from "flowbite-svelte-icons";
import {fightRepo} from "../../../repo/repo.js";
import {replace} from "svelte-spa-router";
import * as dayjs from "dayjs";
export let data: ExtendedEvent;
$: teams = new Map<number, Team>(data.teams.map(team => [team.id, team]));
@ -46,8 +46,8 @@
groups = groups.map((group, i) => i === groupIndex ? [...group.filter(value => value != teamId), teamId] : group.filter(value => value != teamId)).filter(group => group.length > 0);
}
let startTime = moment(data.event.start).utc(true).toISOString().slice(0, -1)
$: startMoment = moment(startTime);
let startTime = dayjs(data.event.start).utc(true).toISOString().slice(0, -1)
$: startMoment = dayjs(startTime);
let gamemode = ''
let map = ''

Datei anzeigen

@ -1,10 +1,9 @@
<script lang="ts">
import {Button, Input, Label, Modal} from "flowbite-svelte";
import moment from "moment";
import {createEventDispatcher} from "svelte";
import ErrorModal from "../../components/ErrorModal.svelte";
import {eventRepo} from "../../../repo/repo.js";
import type {SWEvent} from "../../../types/event.js";
import * as dayjs from "dayjs";
export let open = false;
const dispatch = createEventDispatcher();
@ -14,9 +13,9 @@
let eventName = "";
let start = "";
$: startDate = moment(start)
$: startDate = dayjs(start)
let end = "";
$: endDate = moment(end)
$: endDate = dayjs(end)
$: canSubmit = eventName.length > 0 && startDate.isValid() && endDate.isValid() && startDate.isBefore(endDate)

Datei anzeigen

@ -1,11 +1,7 @@
<script lang="ts">
import {t} from "astro-i18n"
import {createEventDispatcher} from "svelte";
import {schemRepo} from "../repo/repo.ts";
import {schemRepo} from "../repo/repo";
import {Modal, Spinner} from "flowbite-svelte";
import {astroI18n} from "astro-i18n";
import moment from "moment/moment";
import {CheckSolid, XCircleOutline} from "flowbite-svelte-icons";
import SchematicInfoModal from "./SchematicInfoModal.svelte";
import type {Player} from "../types/data.ts";

Datei anzeigen

@ -1,12 +1,12 @@
<script lang="ts">
import {astroI18n, t} from "astro-i18n";
import moment from "moment";
import {CheckSolid, XCircleOutline} from "flowbite-svelte-icons";
import {Modal} from "flowbite-svelte";
import type {SchematicInfo} from "../types/schem.ts";
import {createEventDispatcher} from "svelte";
import {schemRepo} from "../repo/repo.ts";
import {schemRepo} from "../repo/repo";
import type {Player} from "../types/data.ts";
import * as dayjs from "dayjs";
const dispatch = createEventDispatcher();
@ -46,7 +46,7 @@
day: "2-digit",
month: "2-digit",
year: "numeric"
}).format(moment(info.schem.lastUpdate).utc(false).toDate())})}</p>
}).format(dayjs(info.schem.lastUpdate).utc(false).toDate())})}</p>
<p class="!mt-0">{t("dashboard.schematic.info.item", {item: info.schem.item ?? (info.schem.type == null ? "CHEST" : "CAULDRON_ITEM")})}</p>
{#if info.members.length !== 0}
<p class="!mt-0">{t("dashboard.schematic.info.members", {members: info.members.join(", ")})}</p>

Datei anzeigen

@ -1,9 +1,12 @@
<script lang="ts">
import {astroI18n, t} from "astro-i18n";
import moment from "moment/moment.js";
import {CheckSolid, FileOutline, FolderOutline, XCircleOutline} from "flowbite-svelte-icons";
import type {Schematic} from "../types/schem.ts";
import type {Player} from "../types/data.ts";
import * as dayjs from "dayjs";
import * as utc from "dayjs/plugin/utc";
dayjs.extend(utc);
export let schem: Schematic;
export let players: Record<number, Player>;
@ -29,7 +32,7 @@
day: "2-digit",
month: "2-digit",
year: "numeric"
}).format(moment(schem.lastUpdate).utc(false).toDate())}</th>
}).format(dayjs(schem.lastUpdate).utc(false).toDate())}</th>
<th>
{#if schem.replaceColor}
<CheckSolid class="text-green-500" />

Datei anzeigen

@ -33,7 +33,7 @@
dispatch("reset")
}
let uploadFile: File[] | null = null;
let uploadFile: FileList | null = null;
</script>
<Modal title="Upload Schematic" bind:open autoclose outsideclose>

Datei anzeigen

@ -1,20 +1,20 @@
import type {ExtendedEvent, ShortEvent, SWEvent} from "../types/event.js";
import {fetchWithToken} from "./repo.js";
import type {Moment} from "moment";
import {ExtendedEventSchema, ShortEventSchema, SWEventSchema} from "../types/event.js";
import {z} from "zod";
import type {Dayjs} from "dayjs";
export interface CreateEvent {
name: string
start: Moment
end: Moment
start: Dayjs
end: Dayjs
}
export interface UpdateEvent {
name: string
start: Moment
end: Moment
deadline: Moment
start: Dayjs
end: Dayjs
deadline: Dayjs
maxTeamMembers: number
schemType: string | null
publicSchemsOnly: boolean

Datei anzeigen

@ -1,15 +1,15 @@
import type {EventFight} from "../types/event.js";
import {fetchWithToken} from "./repo.js";
import type {Moment} from "moment";
import {z} from "zod";
import {EventFightSchema} from "../types/event.js";
import type {Dayjs} from "dayjs";
export interface CreateFight {
spielmodus: string
map: string
blueTeam: number
redTeam: number
start: Moment
start: Dayjs
kampfleiter: number | null
group: string | null
}
@ -19,7 +19,7 @@ export interface UpdateFight {
map: string | null
blueTeam: number | null
redTeam: number | null
start: Moment | null
start: Dayjs | null
kampfleiter: number | null
group: string | null
}

Datei anzeigen

@ -15,6 +15,7 @@ const iconImage = await getImage({src: icon, height: 32, width: 32, format: 'png
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="description" content={description}/>
<meta name="icbm" content="52.370216;4.895168"/>
<link rel="icon" type="imgage/png" href={iconImage.src} />
<link rel="stylesheet" href="/fonts/barlow-condensed/barlow-condensed.css" />
<title>{title}</title>

Datei anzeigen

@ -27,7 +27,7 @@ const { title } = Astro.props;
</a>
<div class="flex justify-center flex-wrap">
<div class="btn-dropdown my-1">
<div class="btn btn-gray" tabindex="1">
<div class="btn btn-gray" tabindex="0">
<a href={l("/")}>
<span class="btn__text">{t("navbar.links.home.title")}</span>
</a>
@ -41,7 +41,7 @@ const { title } = Astro.props;
</div>
</div>
<div class="btn-dropdown my-1">
<div class="btn btn-gray" tabindex="1">
<div class="btn btn-gray" tabindex="0">
<a rel="prefetch" href={l("/rules")}>
<span class="btn__text">{t("navbar.links.rules.title")}</span>
</a>
@ -101,7 +101,7 @@ const { title } = Astro.props;
}
}
}
;
customElements.define('nav-bar', Navbar);
</script>
<main class="flex-1">

Datei anzeigen

@ -2,11 +2,11 @@
import { getCollection } from "astro:content"
import PageLayout from "../../layouts/PageLayout.astro";
import {astroI18n, t} from "astro-i18n";
import moment from "moment";
import PostComponent from "../../components/PostComponent.astro";
import * as dayjs from "dayjs";
const posts = (await getCollection("announcements", (entry) => entry.id.split("/")[0] === astroI18n.locale))
.sort((a, b) => moment(b.data.created).unix() - moment(a.data.created).unix());
.sort((a, b) => dayjs(b.data.created).unix() - dayjs(a.data.created).unix());
---

Datei anzeigen

@ -1,16 +1,15 @@
---
import moment from "moment/moment";
import {CollectionEntry} from "astro:content";
import {astroI18n, createGetStaticPaths, t} from "astro-i18n";
import {getCollection} from "astro:content";
import PageLayout from "../../../layouts/PageLayout.astro";
import {l} from "../../../util/util";
import {capitalize} from "../../../components/admin/util";
import PostComponent from "../../../components/PostComponent.astro";
import * as dayjs from "dayjs";
export const getStaticPaths = createGetStaticPaths(async () => {
const posts = (await getCollection('announcements', entry => entry.id.split("/")[0] === astroI18n.locale))
.sort((a, b) => moment(b.data.created).unix() - moment(a.data.created).unix());
.sort((a, b) => dayjs(b.data.created).unix() - dayjs(a.data.created).unix());
let groupedByTags: Record<string, CollectionEntry<'announcements'>[]> = {}
posts.forEach(post => {

Datei anzeigen

@ -41,8 +41,7 @@ function mapMap<T, K, J>(i: Map<T, K>, fn: (key: T, value: K) => J): J[] {
<Image src={localBau} alt="Bau" width="1920" height="1080" class="w-screen object-cover rounded-b-2xl shadow-2xl dark:brightness-75" style="height: calc(100vh + 1rem)" draggable="false" />
<drop-in class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 flex flex-col items-center">
<h1 class="text-4xl sm:text-6xl md:text-8xl font-extrabold text-white -translate-y-16 opacity-0 barlow" style="transition: transform .7s ease-out, opacity .7s linear; text-shadow: 2px 2px 5px black;">
<span class="text-yellow-400">{t("home.title.first")}</span>
<span class="text-neutral-600">{t("home.title.second")}</span>
<span class="text-yellow-400">{t("home.title.first")}</span><span class="text-neutral-600">{t("home.title.second")}</span>
</h1>
<text-carousel class="h-20 w-full relative select-none">
<h2 class="-translate-y-16">{t("home.subtitle.1")}</h2>