Compare commits
2 commits
109dec73d2
...
d0d81510cc
Author | SHA1 | Date | |
---|---|---|---|
d0d81510cc | |||
af5abc7c8f |
15 changed files with 235 additions and 408 deletions
|
@ -11,7 +11,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^6.6.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.6.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.6.0",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.8",
|
||||
"@types/chai": "^4.3.17",
|
||||
|
@ -26,11 +25,9 @@
|
|||
"@vue/cli-service": "~5.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vueuse/core": "^10.11.1",
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.7.3",
|
||||
"bulma": "^0.9.4",
|
||||
"bulma-prefers-dark": "^0.1.0-beta.1",
|
||||
"bulma": "^1.0.2",
|
||||
"bulma-toast": "2.4.3",
|
||||
"chai": "^5.1.1",
|
||||
"core-js": "^3.38.0",
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
@charset "utf-8";
|
||||
@use "sass:map";
|
||||
|
||||
//=====================
|
||||
// custom color scheme
|
||||
//=====================
|
||||
|
||||
$advent22-colors: (
|
||||
$colors: (
|
||||
"primary": #945DE1,
|
||||
"link": #64B4BD,
|
||||
"info": #8C4E80,
|
||||
|
@ -13,10 +12,3 @@ $advent22-colors: (
|
|||
"warning": #F6CA6B,
|
||||
"danger": #C5443B,
|
||||
);
|
||||
|
||||
$primary: map.get($advent22-colors, "primary");
|
||||
$link: map.get($advent22-colors, "link");
|
||||
$info: map.get($advent22-colors, "info");
|
||||
$success: map.get($advent22-colors, "success");
|
||||
$warning: map.get($advent22-colors, "warning");
|
||||
$danger: map.get($advent22-colors, "danger");
|
|
@ -78,14 +78,14 @@ export default class extends Vue {
|
|||
|
||||
private multi_modal?: MultiModal;
|
||||
|
||||
public toast?: BulmaToast;
|
||||
public toast?: typeof BulmaToast;
|
||||
private toast_timeout?: number;
|
||||
|
||||
public modal_handle(modal: MultiModal) {
|
||||
this.multi_modal = modal;
|
||||
}
|
||||
|
||||
public toast_handle(toast: BulmaToast) {
|
||||
public toast_handle(toast: typeof BulmaToast) {
|
||||
this.toast = toast;
|
||||
|
||||
if (this.store.is_touch_device) return;
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Step } from "@/lib/helpers";
|
||||
import { DoorSaved } from "@/lib/model";
|
||||
import { Door } from "@/lib/rects/door";
|
||||
import { advent22Store } from "@/lib/store";
|
||||
|
@ -78,7 +79,7 @@ import { API } from "@/lib/api";
|
|||
import { APIError } from "@/lib/api_error";
|
||||
import { toast } from "bulma-toast";
|
||||
import Calendar from "../Calendar.vue";
|
||||
import BulmaBreadcrumbs, { Step } from "../bulma/Breadcrumbs.vue";
|
||||
import BulmaBreadcrumbs from "../bulma/Breadcrumbs.vue";
|
||||
import BulmaButton from "../bulma/Button.vue";
|
||||
import BulmaDrawer from "../bulma/Drawer.vue";
|
||||
import DoorChooser from "../editor/DoorChooser.vue";
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<nav class="breadcrumb has-succeeds-separator">
|
||||
<ul>
|
||||
<li
|
||||
v-for="(step, index) in steps"
|
||||
:key="`step-${index}`"
|
||||
:key="index"
|
||||
:class="modelValue === index ? 'is-active' : ''"
|
||||
@click.left="change_step(index)"
|
||||
>
|
||||
<a>
|
||||
<span class="icon is-small">
|
||||
<font-awesome-icon :icon="step.icon" />
|
||||
<FontAwesomeIcon :icon="step.icon" />
|
||||
</span>
|
||||
<span>{{ step.label }}</span>
|
||||
</a>
|
||||
|
@ -18,31 +19,21 @@
|
|||
</nav>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
<script setup lang="ts">
|
||||
import { Step } from "@/lib/helpers";
|
||||
|
||||
export interface Step {
|
||||
label: string;
|
||||
icon: string;
|
||||
}
|
||||
const props = defineProps<{
|
||||
steps: Step[];
|
||||
modelValue: number;
|
||||
}>();
|
||||
|
||||
@Options({
|
||||
props: {
|
||||
steps: Array,
|
||||
modelValue: Number,
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
})
|
||||
export default class extends Vue {
|
||||
public steps!: Step[];
|
||||
public modelValue!: number;
|
||||
const emit = defineEmits<{
|
||||
"update:modelValue": [number];
|
||||
}>();
|
||||
|
||||
public change_step(next_step: number) {
|
||||
if (next_step === this.modelValue) {
|
||||
return;
|
||||
}
|
||||
function change_step(next_step: number) {
|
||||
if (next_step === props.modelValue) return;
|
||||
|
||||
this.$emit("update:modelValue", next_step);
|
||||
}
|
||||
emit("update:modelValue", next_step);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,45 +1,28 @@
|
|||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<button class="button">
|
||||
<slot v-if="text === undefined" name="default">
|
||||
<font-awesome-icon
|
||||
<slot name="default">
|
||||
<span v-if="icon !== undefined" class="icon">
|
||||
<FontAwesomeIcon
|
||||
v-if="icon !== undefined"
|
||||
:icon="icon"
|
||||
:beat-fade="busy"
|
||||
/>
|
||||
</slot>
|
||||
<template v-else>
|
||||
<span v-if="icon !== undefined" class="icon">
|
||||
<slot name="default">
|
||||
<font-awesome-icon :icon="icon" :beat-fade="busy" />
|
||||
</slot>
|
||||
</span>
|
||||
<span>{{ text }}</span>
|
||||
</template>
|
||||
</slot>
|
||||
<span v-if="text !== undefined">{{ text }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
@Options({
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
required: false,
|
||||
<script setup lang="ts">
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
icon?: string | string[];
|
||||
text?: string;
|
||||
busy?: boolean;
|
||||
}>(),
|
||||
{
|
||||
busy: false,
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
busy: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
export default class extends Vue {
|
||||
public icon?: string;
|
||||
public text?: string;
|
||||
public busy!: boolean;
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
|
|
@ -1,36 +1,37 @@
|
|||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<div class="card">
|
||||
<header class="card-header is-unselectable" style="cursor: pointer">
|
||||
<p class="card-header-title" @click="toggle">{{ header }}</p>
|
||||
|
||||
<p v-if="refreshable" class="card-header-icon px-0">
|
||||
<BulmaButton class="tag icon is-primary" @click="refresh">
|
||||
<font-awesome-icon
|
||||
icon="fa-solid fa-arrows-rotate"
|
||||
:spin="is_open && loading"
|
||||
<BulmaButton class="is-small is-primary" @click="refresh">
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'arrows-rotate']"
|
||||
:spin="is_open && state === 'loading'"
|
||||
/>
|
||||
</BulmaButton>
|
||||
</p>
|
||||
|
||||
<button class="card-header-icon" @click="toggle">
|
||||
<span class="icon">
|
||||
<font-awesome-icon
|
||||
:icon="'fa-solid fa-angle-' + (is_open ? 'down' : 'right')"
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', is_open ? 'angle-down' : 'angle-right']"
|
||||
/>
|
||||
</span>
|
||||
</button>
|
||||
</header>
|
||||
|
||||
<template v-if="is_open">
|
||||
<div v-if="loading" class="card-content">
|
||||
<progress class="progress is-primary" max="100" />
|
||||
<div v-if="state === 'loading'" class="card-content">
|
||||
<progress class="progress is-primary" />
|
||||
</div>
|
||||
<div
|
||||
v-else-if="failed"
|
||||
v-else-if="state === 'failed'"
|
||||
class="card-content has-text-danger has-text-centered"
|
||||
>
|
||||
<span class="icon is-large">
|
||||
<font-awesome-icon icon="fa-solid fa-ban" size="3x" />
|
||||
<FontAwesomeIcon :icon="['fas', 'ban']" size="3x" />
|
||||
</span>
|
||||
</div>
|
||||
<slot v-else name="default" />
|
||||
|
@ -38,63 +39,46 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import BulmaButton from "./Button.vue";
|
||||
|
||||
enum DrawerState {
|
||||
Loading,
|
||||
Ready,
|
||||
Failed,
|
||||
}
|
||||
|
||||
@Options({
|
||||
components: {
|
||||
BulmaButton,
|
||||
},
|
||||
props: {
|
||||
header: String,
|
||||
refreshable: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ["open"],
|
||||
})
|
||||
export default class extends Vue {
|
||||
public header!: string;
|
||||
public refreshable!: boolean;
|
||||
|
||||
public is_open = false;
|
||||
public state = DrawerState.Loading;
|
||||
|
||||
public toggle() {
|
||||
this.is_open = !this.is_open;
|
||||
|
||||
if (this.is_open) {
|
||||
this.state = DrawerState.Loading;
|
||||
|
||||
this.$emit(
|
||||
"open",
|
||||
() => (this.state = DrawerState.Ready),
|
||||
() => (this.state = DrawerState.Failed),
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
header: string;
|
||||
refreshable?: boolean;
|
||||
}>(),
|
||||
{ refreshable: false },
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
open: [
|
||||
{
|
||||
ready(): void;
|
||||
fail(): void;
|
||||
},
|
||||
];
|
||||
}>();
|
||||
|
||||
const is_open = ref(false);
|
||||
const state = ref<"loading" | "ready" | "failed">("loading");
|
||||
|
||||
function toggle() {
|
||||
is_open.value = !is_open.value;
|
||||
|
||||
if (is_open.value) {
|
||||
state.value = "loading";
|
||||
|
||||
emit("open", {
|
||||
ready: () => (state.value = "ready"),
|
||||
fail: () => (state.value = "failed"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public refresh() {
|
||||
this.is_open = false;
|
||||
this.toggle();
|
||||
}
|
||||
|
||||
public get loading(): boolean {
|
||||
return this.state === DrawerState.Loading;
|
||||
}
|
||||
|
||||
public get failed(): boolean {
|
||||
return this.state === DrawerState.Failed;
|
||||
}
|
||||
function refresh() {
|
||||
is_open.value = false;
|
||||
toggle();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1,68 +1,47 @@
|
|||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<slot v-if="show" name="default" />
|
||||
<slot v-if="state === 'show'" name="default" />
|
||||
<span v-else>***</span>
|
||||
<BulmaButton
|
||||
:class="`tag icon is-${button_class} ml-2`"
|
||||
:icon="`fa-solid fa-${button_icon}`"
|
||||
:busy="busy"
|
||||
:class="`is-small is-${button_class} ml-2`"
|
||||
:icon="['fas', `${button_icon}`]"
|
||||
:busy="state === 'click'"
|
||||
@click="on_click"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import BulmaButton from "./Button.vue";
|
||||
|
||||
enum ClickState {
|
||||
Green = 0,
|
||||
Yellow = 1,
|
||||
Red = 2,
|
||||
}
|
||||
const emit = defineEmits<{
|
||||
load: [];
|
||||
}>();
|
||||
|
||||
@Options({
|
||||
components: {
|
||||
BulmaButton,
|
||||
},
|
||||
emits: ["load"],
|
||||
})
|
||||
export default class extends Vue {
|
||||
public state = ClickState.Green;
|
||||
const state = ref<"start" | "click" | "show">("start");
|
||||
const button_class = ref<"primary" | "warning" | "danger">("primary");
|
||||
const button_icon = ref<"eye-slash" | "eye">("eye-slash");
|
||||
|
||||
public on_click(): void {
|
||||
this.state++;
|
||||
this.state %= 3;
|
||||
function on_click(): void {
|
||||
switch (state.value) {
|
||||
case "show":
|
||||
state.value = "start";
|
||||
button_class.value = "primary";
|
||||
button_icon.value = "eye-slash";
|
||||
break;
|
||||
|
||||
if (this.state === ClickState.Red) {
|
||||
this.$emit("load");
|
||||
}
|
||||
}
|
||||
case "start":
|
||||
state.value = "click";
|
||||
button_class.value = "warning";
|
||||
button_icon.value = "eye-slash";
|
||||
break;
|
||||
|
||||
public get show(): boolean {
|
||||
return this.state === ClickState.Red;
|
||||
}
|
||||
|
||||
public get busy(): boolean {
|
||||
return this.state === ClickState.Yellow;
|
||||
}
|
||||
|
||||
public get button_class(): string {
|
||||
switch (this.state) {
|
||||
case ClickState.Red:
|
||||
return "danger";
|
||||
case ClickState.Yellow:
|
||||
return "warning";
|
||||
default:
|
||||
return "primary";
|
||||
}
|
||||
}
|
||||
|
||||
public get button_icon(): string {
|
||||
if (this.state === ClickState.Red) {
|
||||
return "eye-slash";
|
||||
} else {
|
||||
return "eye";
|
||||
}
|
||||
case "click":
|
||||
state.value = "show";
|
||||
button_class.value = "danger";
|
||||
button_icon.value = "eye";
|
||||
emit("load");
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<div style="display: none">
|
||||
<div v-bind="$attrs" ref="message">
|
||||
|
@ -6,38 +7,43 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import * as bulmaToast from "bulma-toast";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
import { onMounted, ref } from "vue";
|
||||
|
||||
@Options({
|
||||
emits: ["handle"],
|
||||
})
|
||||
export default class extends Vue {
|
||||
public created(): void {
|
||||
this.$emit("handle", this);
|
||||
}
|
||||
const emit = defineEmits<{
|
||||
handle: [
|
||||
{
|
||||
show(options: bulmaToast.Options): void;
|
||||
hide(): void;
|
||||
},
|
||||
];
|
||||
}>();
|
||||
|
||||
public show(options: bulmaToast.Options = {}) {
|
||||
if (!(this.$refs.message instanceof HTMLElement)) return;
|
||||
const message = ref<HTMLDivElement | null>(null);
|
||||
|
||||
onMounted(() =>
|
||||
emit("handle", {
|
||||
show(options: bulmaToast.Options = {}) {
|
||||
if (!(message.value instanceof HTMLElement)) return;
|
||||
|
||||
bulmaToast.toast({
|
||||
...options,
|
||||
single: true,
|
||||
message: this.$refs.message,
|
||||
message: message.value,
|
||||
});
|
||||
}
|
||||
},
|
||||
hide() {
|
||||
if (!(message.value instanceof HTMLElement)) return;
|
||||
|
||||
public hide() {
|
||||
if (!(this.$refs.message instanceof HTMLElement)) return;
|
||||
|
||||
const toast_div = this.$refs.message.parentElement;
|
||||
const toast_div = message.value.parentElement;
|
||||
if (!(toast_div instanceof HTMLDivElement)) return;
|
||||
|
||||
const dbutton = toast_div.querySelector("button.delete");
|
||||
if (!(dbutton instanceof HTMLButtonElement)) return;
|
||||
|
||||
dbutton.click();
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
);
|
||||
</script>
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
<template>
|
||||
<foreignObject
|
||||
:x="Math.round(aspect_ratio * rectangle.left)"
|
||||
:x="Math.round(get_bg_aspect_ratio() * rectangle.left)"
|
||||
:y="rectangle.top"
|
||||
:width="Math.round(aspect_ratio * rectangle.width)"
|
||||
:width="Math.round(get_bg_aspect_ratio() * rectangle.width)"
|
||||
:height="rectangle.height"
|
||||
:style="`transform: scaleX(${1 / aspect_ratio})`"
|
||||
:style="`transform: scaleX(${1 / get_bg_aspect_ratio()})`"
|
||||
>
|
||||
<div
|
||||
xmlns="http://www.w3.org/1999/xhtml"
|
||||
:class="`px-2 is-flex is-align-items-center is-justify-content-center is-size-2 has-text-weight-bold ${extra_classes}`"
|
||||
:class="`px-2 is-flex is-align-items-center is-justify-content-center is-size-2 has-text-weight-bold ${variant} ${
|
||||
visible ? 'visible' : ''
|
||||
}`"
|
||||
style="height: inherit"
|
||||
:title="title"
|
||||
v-bind="$attrs"
|
||||
>
|
||||
<slot name="default" />
|
||||
</div>
|
||||
</foreignObject>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { loading_success } from "@/lib/helpers";
|
||||
import { Rectangle } from "@/lib/rects/rectangle";
|
||||
import { advent22Store } from "@/lib/store";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
const store = advent22Store();
|
||||
|
||||
type BulmaVariant =
|
||||
| "primary"
|
||||
|
@ -31,48 +34,26 @@ type BulmaVariant =
|
|||
| "warning"
|
||||
| "danger";
|
||||
|
||||
@Options({
|
||||
props: {
|
||||
variant: String,
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
variant: BulmaVariant;
|
||||
visible?: boolean;
|
||||
rectangle: Rectangle;
|
||||
}>(),
|
||||
{
|
||||
visible: true,
|
||||
},
|
||||
rectangle: Rectangle,
|
||||
title: {
|
||||
type: String,
|
||||
required: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
export default class extends Vue {
|
||||
public readonly store = advent22Store();
|
||||
|
||||
private variant!: BulmaVariant;
|
||||
private visible!: boolean;
|
||||
public rectangle!: Rectangle;
|
||||
public title?: string;
|
||||
|
||||
public get extra_classes(): string {
|
||||
let result = this.variant;
|
||||
|
||||
if (this.visible) result += " visible";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public get aspect_ratio(): number {
|
||||
if (!loading_success(this.store.background_image)) return 1;
|
||||
|
||||
return (
|
||||
this.store.background_image.height / this.store.background_image.width
|
||||
);
|
||||
}
|
||||
|
||||
function get_bg_aspect_ratio(): number {
|
||||
if (!loading_success(store.background_image)) return 1;
|
||||
|
||||
return store.background_image.height / store.background_image.width;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/bulma-scheme";
|
||||
@use "@/bulma-scheme" as scheme;
|
||||
|
||||
foreignObject > div {
|
||||
&:not(.visible, :hover):deep() > * {
|
||||
|
@ -84,7 +65,7 @@ foreignObject > div {
|
|||
border-width: 2px;
|
||||
border-style: solid;
|
||||
|
||||
@each $name, $color in $advent22-colors {
|
||||
@each $name, $color in scheme.$colors {
|
||||
&.#{$name} {
|
||||
background-color: rgba($color, 0.3);
|
||||
border-color: rgba($color, 0.9);
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
</svg>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { Vector2D } from "@/lib/rects/vector2d";
|
||||
import { advent22Store } from "@/lib/store";
|
||||
import { Options, Vue } from "vue-class-component";
|
||||
|
||||
function get_event_thous(event: MouseEvent): Vector2D {
|
||||
if (!(event.currentTarget instanceof SVGSVGElement)) {
|
||||
|
@ -31,36 +29,22 @@ function get_event_thous(event: MouseEvent): Vector2D {
|
|||
);
|
||||
}
|
||||
|
||||
function mouse_event_validator(event: object, point: object): boolean {
|
||||
if (!(event instanceof MouseEvent)) {
|
||||
console.warn(event, "is not a MouseEvent!");
|
||||
return false;
|
||||
}
|
||||
type TCMouseEvent = [MouseEvent, Vector2D];
|
||||
|
||||
if (!(point instanceof Vector2D)) {
|
||||
console.warn(point, "is not a Vector2D!");
|
||||
return false;
|
||||
}
|
||||
const emit = defineEmits<{
|
||||
mousedown: TCMouseEvent;
|
||||
mouseup: TCMouseEvent;
|
||||
mousemove: TCMouseEvent;
|
||||
click: TCMouseEvent;
|
||||
dblclick: TCMouseEvent;
|
||||
}>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Options({
|
||||
emits: {
|
||||
mousedown: mouse_event_validator,
|
||||
mouseup: mouse_event_validator,
|
||||
mousemove: mouse_event_validator,
|
||||
click: mouse_event_validator,
|
||||
dblclick: mouse_event_validator,
|
||||
},
|
||||
})
|
||||
export default class extends Vue {
|
||||
public readonly store = advent22Store();
|
||||
|
||||
public transform_mouse_event(event: MouseEvent) {
|
||||
function transform_mouse_event(event: MouseEvent) {
|
||||
const point = get_event_thous(event);
|
||||
this.$emit(event.type, event, point);
|
||||
}
|
||||
|
||||
// mute a useless typescript error
|
||||
const event_type = event.type as "mousedown";
|
||||
emit(event_type, event, point);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -37,3 +37,8 @@ export function handle_error(error: unknown) {
|
|||
export function name_door(day: number): string {
|
||||
return `Türchen ${day}`;
|
||||
}
|
||||
|
||||
export interface Step {
|
||||
label: string;
|
||||
icon: string | string[];
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ export const advent22Store = defineStore({
|
|||
document.getElementsByTagName("head")[0].appendChild(link);
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
const [is_admin, site_config, background_image, user_doors, next_door] =
|
||||
await Promise.all([
|
||||
this.update_is_admin(),
|
||||
|
@ -91,6 +92,9 @@ export const advent22Store = defineStore({
|
|||
}
|
||||
|
||||
if (next_door !== null) this.next_door_target = Date.now() + next_door;
|
||||
} catch {
|
||||
this.background_image = "error";
|
||||
}
|
||||
},
|
||||
|
||||
when_initialized(callback: () => void): void {
|
||||
|
|
|
@ -1,64 +1,23 @@
|
|||
@charset "utf-8";
|
||||
@use "sass:map";
|
||||
|
||||
//===========
|
||||
// variables
|
||||
//===========
|
||||
//==============
|
||||
// bulma
|
||||
//==============
|
||||
|
||||
// custom color scheme
|
||||
@import "@/bulma-scheme";
|
||||
|
||||
// Sass variables (bulma)
|
||||
@import "~bulma/sass/utilities/initial-variables.sass";
|
||||
@import "~bulma/sass/utilities/derived-variables.sass";
|
||||
|
||||
// Sass variables (bulma-prefers-dark)
|
||||
@import "~bulma-prefers-dark/sass/utilities/initial-variables.sass";
|
||||
@import "~bulma-prefers-dark/sass/utilities/derived-variables.sass";
|
||||
|
||||
//=================
|
||||
// variable tweaks
|
||||
//=================
|
||||
|
||||
$modal-card-body-background-color-dark: $body-background-dark;
|
||||
$card-background-color-dark: $background-dark;
|
||||
@use "bulma-scheme" as scheme;
|
||||
@use "bulma/sass" with (
|
||||
$primary: map.get(scheme.$colors, "primary"),
|
||||
$link: map.get(scheme.$colors, "link"),
|
||||
$info: map.get(scheme.$colors, "info"),
|
||||
$success: map.get(scheme.$colors, "success"),
|
||||
$warning: map.get(scheme.$colors, "warning"),
|
||||
$danger: map.get(scheme.$colors, "danger")
|
||||
);
|
||||
|
||||
//==============
|
||||
// main imports
|
||||
//==============
|
||||
|
||||
@import "~animate.css/animate";
|
||||
@import "~bulma/bulma";
|
||||
@import "~bulma-prefers-dark/bulma-prefers-dark";
|
||||
|
||||
//==============
|
||||
// style tweaks
|
||||
//==============
|
||||
|
||||
.card-header {
|
||||
background-color: $background;
|
||||
|
||||
@include prefers-scheme(dark) {
|
||||
background-color: $card-header-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
@include prefers-scheme(dark) {
|
||||
background-color: $body-background-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
// &::-webkit-progress-bar {
|
||||
// background-color: transparent !important;
|
||||
// }
|
||||
// &::-webkit-progress-value {
|
||||
// background-color: transparent !important;
|
||||
// }
|
||||
&::-moz-progress-bar {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
// &::-ms-fill {
|
||||
// background-color: transparent !important;
|
||||
// }
|
||||
}
|
||||
@import "animate.css/animate";
|
||||
|
|
49
ui/yarn.lock
49
ui/yarn.lock
|
@ -1084,13 +1084,6 @@
|
|||
dependencies:
|
||||
"@fortawesome/fontawesome-common-types" "6.6.0"
|
||||
|
||||
"@fortawesome/free-brands-svg-icons@^6.6.0":
|
||||
version "6.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz#2797f2cc66d21e7e47fa64e680b8835e8d30e825"
|
||||
integrity sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ==
|
||||
dependencies:
|
||||
"@fortawesome/fontawesome-common-types" "6.6.0"
|
||||
|
||||
"@fortawesome/free-solid-svg-icons@^6.6.0":
|
||||
version "6.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b"
|
||||
|
@ -1492,11 +1485,6 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/web-bluetooth@^0.0.20":
|
||||
version "0.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
|
||||
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
|
||||
|
||||
"@types/webpack-env@^1.15.2":
|
||||
version "1.18.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.4.tgz#62879b0a9c653f9b1172d403b882f2045ecce032"
|
||||
|
@ -2006,28 +1994,6 @@
|
|||
resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz#b6b40a7625429d2bd7c2281ddba601ed05dc7f1a"
|
||||
integrity sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==
|
||||
|
||||
"@vueuse/core@^10.11.1":
|
||||
version "10.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.11.1.tgz#15d2c0b6448d2212235b23a7ba29c27173e0c2c6"
|
||||
integrity sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==
|
||||
dependencies:
|
||||
"@types/web-bluetooth" "^0.0.20"
|
||||
"@vueuse/metadata" "10.11.1"
|
||||
"@vueuse/shared" "10.11.1"
|
||||
vue-demi ">=0.14.8"
|
||||
|
||||
"@vueuse/metadata@10.11.1":
|
||||
version "10.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.11.1.tgz#209db7bb5915aa172a87510b6de2ca01cadbd2a7"
|
||||
integrity sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==
|
||||
|
||||
"@vueuse/shared@10.11.1":
|
||||
version "10.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.11.1.tgz#62b84e3118ae6e1f3ff38f4fbe71b0c5d0f10938"
|
||||
integrity sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==
|
||||
dependencies:
|
||||
vue-demi ">=0.14.8"
|
||||
|
||||
"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5":
|
||||
version "1.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"
|
||||
|
@ -2574,20 +2540,15 @@ buffer@^5.5.0:
|
|||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
bulma-prefers-dark@^0.1.0-beta.1:
|
||||
version "0.1.0-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/bulma-prefers-dark/-/bulma-prefers-dark-0.1.0-beta.1.tgz#074aa71899f389a0137dd3753f0d89e96ab1e59b"
|
||||
integrity sha512-ti4sKxIIrTAvGtsYc9Rk66SUZSH/j63EU1hApQijQVlKFF0qBLGSb8E16HhI83KJaIeYP4aAHQv2tj0ara831A==
|
||||
|
||||
bulma-toast@2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/bulma-toast/-/bulma-toast-2.4.3.tgz#cd302ad5ed625f47d7426b48b741250950e1cbf9"
|
||||
integrity sha512-OpNn3MUD27ne8RkQns3yS7HaltU5/s67ivbdxAb/gXjxmfZhIdoeUFPYkopEXwCpzc+VasYy1OAglGIFvjEvUQ==
|
||||
|
||||
bulma@^0.9.4:
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.4.tgz#0ca8aeb1847a34264768dba26a064c8be72674a1"
|
||||
integrity sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==
|
||||
bulma@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/bulma/-/bulma-1.0.2.tgz#47395a660755c9566db3cf981fd4e3a2b637af19"
|
||||
integrity sha512-D7GnDuF6seb6HkcnRMM9E739QpEY9chDzzeFrHMyEns/EXyDJuQ0XA0KxbBl/B2NTsKSoDomW61jFGFaAxhK5A==
|
||||
|
||||
bytes@3.0.0:
|
||||
version "3.0.0"
|
||||
|
@ -7079,7 +7040,7 @@ vue-component-type-helpers@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-2.0.7.tgz#f142e82440da61fa81671ac2f35fd87146248897"
|
||||
integrity sha512-7e12Evdll7JcTIocojgnCgwocX4WzIYStGClBQ+QuWPinZo/vQolv2EMq4a3lg16TKfwWafLimG77bxb56UauA==
|
||||
|
||||
vue-demi@>=0.14.8, vue-demi@^0.14.10:
|
||||
vue-demi@^0.14.10:
|
||||
version "0.14.10"
|
||||
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.10.tgz#afc78de3d6f9e11bf78c55e8510ee12814522f04"
|
||||
integrity sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==
|
||||
|
|
Loading…
Reference in a new issue