added plugins/store.ts using "pinia" to define input mode

This commit is contained in:
Jörn-Michael Miehe 2023-11-01 23:58:09 +00:00
parent 19411351dd
commit a0b576e14d
7 changed files with 103 additions and 24 deletions

View file

@ -34,6 +34,7 @@
"eslint": "^8.49.0", "eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0", "eslint-plugin-vue": "^9.17.0",
"luxon": "^3.4.3", "luxon": "^3.4.3",
"pinia": "^2.1.7",
"sass": "^1.67.0", "sass": "^1.67.0",
"sass-loader": "^13.3.2", "sass-loader": "^13.3.2",
"typescript": "~5.2.2", "typescript": "~5.2.2",

View file

@ -1,5 +1,5 @@
<template> <template>
<section class="hero is-small is-primary" style="overflow-x: auto"> <section class="hero is-small is-primary">
<div class="hero-body"> <div class="hero-body">
<h1 class="title is-uppercase">{{ title }}</h1> <h1 class="title is-uppercase">{{ title }}</h1>
<h2 class="subtitle">{{ subtitle }}</h2> <h2 class="subtitle">{{ subtitle }}</h2>
@ -21,6 +21,7 @@
<p v-html="footer" /> <p v-html="footer" />
</div> </div>
<div class="level-right"> <div class="level-right">
<TouchButton class="level-item tag is-warning" />
<AdminButton <AdminButton
class="level-item tag is-link is-outlined" class="level-item tag is-link is-outlined"
v-model="is_admin" v-model="is_admin"
@ -35,12 +36,14 @@ import { Options, Vue } from "vue-class-component";
import AdminView from "./components/admin/AdminView.vue"; import AdminView from "./components/admin/AdminView.vue";
import AdminButton from "./components/AdminButton.vue"; import AdminButton from "./components/AdminButton.vue";
import TouchButton from "./components/TouchButton.vue";
import UserView from "./components/UserView.vue"; import UserView from "./components/UserView.vue";
@Options({ @Options({
components: { components: {
AdminView, AdminView,
AdminButton, AdminButton,
TouchButton,
UserView, UserView,
}, },
}) })

View file

@ -2,27 +2,13 @@
<MultiModal @handle="modal_handle" /> <MultiModal @handle="modal_handle" />
<figure> <figure>
<div class="level"> <figcaption class="has-text-primary-dark">
<div class="level-left">
<figcaption class="level-item has-text-primary-dark">
{{ figure_caption }} {{ figure_caption }}
<template v-if="next_door !== null"> <template v-if="next_door !== null">
<br /> <br />
Zeit zum nächsten Türchen: <CountDown :millis="next_door" /> Zeit zum nächsten Türchen: <CountDown :millis="next_door" />
</template> </template>
</figcaption> </figcaption>
</div>
<div class="level-right">
<div class="level-item">
<BulmaButton
class="tag is-warning is-outlined"
text="Türchen anzeigen"
:icon="'fa-solid fa-toggle-' + (show_doors ? 'on' : 'off')"
@click.left="show_doors = !show_doors"
/>
</div>
</div>
</div>
<div class="image is-unselectable"> <div class="image is-unselectable">
<img :src="$advent22.api_url('user/background_image')" /> <img :src="$advent22.api_url('user/background_image')" />
<ThouCanvas> <ThouCanvas>
@ -30,7 +16,7 @@
v-for="(door, index) in doors" v-for="(door, index) in doors"
:key="`door-${index}`" :key="`door-${index}`"
:door="door" :door="door"
:visible="show_doors" :visible="store.is_touch_device"
@click="door_click(door.day)" @click="door_click(door.day)"
@touch="door_hover(door.day)" @touch="door_hover(door.day)"
@mouseover="door_hover(door.day)" @mouseover="door_hover(door.day)"
@ -44,6 +30,7 @@
<script lang="ts"> <script lang="ts">
import { Door } from "@/lib/door"; import { Door } from "@/lib/door";
import { advent22Store } from "@/plugins/store";
import { Options, Vue } from "vue-class-component"; import { Options, Vue } from "vue-class-component";
import CountDown from "./CountDown.vue"; import CountDown from "./CountDown.vue";
@ -67,8 +54,8 @@ import ThouCanvas from "./calendar/ThouCanvas.vue";
export default class extends Vue { export default class extends Vue {
public readonly doors!: Door[]; public readonly doors!: Door[];
private readonly idle_caption = "Finde die Türchen auf dem Adventskalender!"; private readonly idle_caption = "Finde die Türchen auf dem Adventskalender!";
public readonly store = advent22Store();
public show_doors = window.matchMedia("(any-hover: none)").matches;
private multi_modal?: MultiModal; private multi_modal?: MultiModal;
public figure_caption = this.idle_caption; public figure_caption = this.idle_caption;
public next_door: number | null = null; public next_door: number | null = null;

View file

@ -0,0 +1,26 @@
<template>
<BulmaButton
:icon="
'fa-solid fa-' +
(store.is_touch_device ? 'hand-pointer' : 'arrow-pointer')
"
text="Eingabemodus"
@click.left="store.toggle_touch_device"
/>
</template>
<script lang="ts">
import { advent22Store } from "@/plugins/store";
import { Options, Vue } from "vue-class-component";
import BulmaButton from "./bulma/Button.vue";
@Options({
components: {
BulmaButton,
},
})
export default class extends Vue {
public readonly store = advent22Store();
}
</script>

View file

@ -1,5 +1,6 @@
import { Advent22Plugin } from "@/plugins/advent22"; import { Advent22Plugin } from "@/plugins/advent22";
import { FontAwesomePlugin } from "@/plugins/fontawesome"; import { FontAwesomePlugin } from "@/plugins/fontawesome";
import { createPinia } from "pinia";
import { createApp } from "vue"; import { createApp } from "vue";
import App from "./App.vue"; import App from "./App.vue";
@ -8,5 +9,6 @@ import "@/main.scss";
const app = createApp(App); const app = createApp(App);
app.use(Advent22Plugin); app.use(Advent22Plugin);
app.use(FontAwesomePlugin); app.use(FontAwesomePlugin);
app.use(createPinia());
app.mount("#app"); app.mount("#app");

42
ui/src/plugins/store.ts Normal file
View file

@ -0,0 +1,42 @@
// import { Credentials } from "@/lib/api";
// import { AxiosBasicCredentials } from "axios";
import { acceptHMRUpdate, defineStore } from "pinia";
const check_touch_device = () => window.matchMedia("(any-hover: none)").matches;
// const empty_creds = () => ["", ""] as Credentials;
export const advent22Store = defineStore({
id: "advent22",
state: () => ({
// api_creds: empty_creds(),
is_touch_device: check_touch_device(),
}),
// getters: {
// axios_creds: (state): AxiosBasicCredentials => {
// const [username, password] = state.api_creds;
// return { username: username, password: password };
// },
// },
actions: {
// set_api_creds(creds: Credentials = empty_creds()): void {
// this.api_creds = creds;
// },
set_touch_device(state: boolean = check_touch_device()): void {
this.is_touch_device = state;
},
toggle_touch_device(): void {
this.is_touch_device = !this.is_touch_device;
},
},
});
if (import.meta.webpackHot) {
import.meta.webpackHot.accept(
acceptHMRUpdate(advent22Store, import.meta.webpackHot),
);
}

View file

@ -1854,6 +1854,11 @@
optionalDependencies: optionalDependencies:
prettier "^1.18.2 || ^2.0.0" prettier "^1.18.2 || ^2.0.0"
"@vue/devtools-api@^6.5.0":
version "6.5.1"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.5.1.tgz#7f71f31e40973eeee65b9a64382b13593fdbd697"
integrity sha512-+KpckaAQyfbvshdDW5xQylLni1asvNSGme1JFs8I1+/H5pHEhqUKMEQD/qn3Nx5+/nycBq11qAEi8lk+LXI2dA==
"@vue/eslint-config-typescript@^12.0.0": "@vue/eslint-config-typescript@^12.0.0":
version "12.0.0" version "12.0.0"
resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz#0ce22d97af5e4155f3f2e7b21a48cfde8a6f3365" resolved "https://registry.yarnpkg.com/@vue/eslint-config-typescript/-/eslint-config-typescript-12.0.0.tgz#0ce22d97af5e4155f3f2e7b21a48cfde8a6f3365"
@ -5486,6 +5491,14 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
pinia@^2.1.7:
version "2.1.7"
resolved "https://registry.yarnpkg.com/pinia/-/pinia-2.1.7.tgz#4cf5420d9324ca00b7b4984d3fbf693222115bbc"
integrity sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==
dependencies:
"@vue/devtools-api" "^6.5.0"
vue-demi ">=0.14.5"
pkg-dir@^4.1.0: pkg-dir@^4.1.0:
version "4.2.0" version "4.2.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3"
@ -6835,6 +6848,11 @@ vue-component-type-helpers@1.8.4:
resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz#302d85fac912519cdf0dd2fb51402e5215d85628" resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-1.8.4.tgz#302d85fac912519cdf0dd2fb51402e5215d85628"
integrity sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ== integrity sha512-6bnLkn8O0JJyiFSIF0EfCogzeqNXpnjJ0vW/SZzNHfe6sPx30lTtTXlE5TFs2qhJlAtDFybStVNpL73cPe3OMQ==
vue-demi@>=0.14.5:
version "0.14.6"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.6.tgz#dc706582851dc1cdc17a0054f4fec2eb6df74c92"
integrity sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==
vue-eslint-parser@^9.3.1: vue-eslint-parser@^9.3.1:
version "9.3.1" version "9.3.1"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz#429955e041ae5371df5f9e37ebc29ba046496182" resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-9.3.1.tgz#429955e041ae5371df5f9e37ebc29ba046496182"