diff options
Diffstat (limited to 'src/client')
| -rw-r--r-- | src/client/account.ts | 38 | ||||
| -rwxr-xr-x | src/client/components/signin.vue | 6 | ||||
| -rw-r--r-- | src/client/components/signup.vue | 4 | ||||
| -rw-r--r-- | src/client/pages/federation.vue | 12 | ||||
| -rw-r--r-- | src/client/pages/settings/general.vue | 9 | ||||
| -rw-r--r-- | src/client/pages/settings/privacy.vue | 2 | ||||
| -rw-r--r-- | src/client/pages/welcome.setup.vue | 2 | ||||
| -rw-r--r-- | src/client/store.ts | 4 | ||||
| -rw-r--r-- | src/client/style.scss | 1 | ||||
| -rw-r--r-- | src/client/tsconfig.json | 3 | ||||
| -rw-r--r-- | src/client/ui/default.vue | 31 | ||||
| -rw-r--r-- | src/client/widgets/aichan.vue | 59 | ||||
| -rw-r--r-- | src/client/widgets/index.ts | 2 |
13 files changed, 146 insertions, 27 deletions
diff --git a/src/client/account.ts b/src/client/account.ts index ee1d845493..e469bae5a2 100644 --- a/src/client/account.ts +++ b/src/client/account.ts @@ -1,4 +1,4 @@ -import { get, set } from '@client/scripts/idb-proxy'; +import { del, get, set } from '@client/scripts/idb-proxy'; import { reactive } from 'vue'; import { apiUrl } from '@client/config'; import { waiting } from '@client/os'; @@ -26,21 +26,33 @@ export async function signout() { //#region Remove account const accounts = await getAccounts(); accounts.splice(accounts.findIndex(x => x.id === $i.id), 1); - set('accounts', accounts); + + if (accounts.length > 0) await set('accounts', accounts); + else await del('accounts'); //#endregion - //#region Remove push notification registration + //#region Remove service worker registration try { - const registration = await navigator.serviceWorker.ready; - const push = await registration.pushManager.getSubscription(); - if (!push) return; - await fetch(`${apiUrl}/sw/unregister`, { - method: 'POST', - body: JSON.stringify({ - i: $i.token, - endpoint: push.endpoint, - }), - }); + if (navigator.serviceWorker.controller) { + const registration = await navigator.serviceWorker.ready; + const push = await registration.pushManager.getSubscription(); + if (push) { + await fetch(`${apiUrl}/sw/unregister`, { + method: 'POST', + body: JSON.stringify({ + i: $i.token, + endpoint: push.endpoint, + }), + }); + } + } + + if (accounts.length === 0) { + await navigator.serviceWorker.getRegistrations() + .then(registrations => { + return Promise.all(registrations.map(registration => registration.unregister())); + }); + } } catch (e) {} //#endregion diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue index 0094038fb6..c051288d0a 100755 --- a/src/client/components/signin.vue +++ b/src/client/components/signin.vue @@ -111,7 +111,9 @@ export default defineComponent({ onLogin(res) { if (this.autoSet) { - login(res.i); + return login(res.i); + } else { + return; } }, @@ -144,7 +146,7 @@ export default defineComponent({ }); }).then(res => { this.$emit('login', res); - this.onLogin(res); + return this.onLogin(res); }).catch(err => { if (err === null) return; os.dialog({ diff --git a/src/client/components/signup.vue b/src/client/components/signup.vue index d584b97209..d332274111 100644 --- a/src/client/components/signup.vue +++ b/src/client/components/signup.vue @@ -178,14 +178,14 @@ export default defineComponent({ 'hcaptcha-response': this.hCaptchaResponse, 'g-recaptcha-response': this.reCaptchaResponse, }).then(() => { - os.api('signin', { + return os.api('signin', { username: this.username, password: this.password }).then(res => { this.$emit('signup', res); if (this.autoSet) { - login(res.i); + return login(res.i); } }); }).catch(() => { diff --git a/src/client/pages/federation.vue b/src/client/pages/federation.vue index f4ab9d0ec3..2afe70eea6 100644 --- a/src/client/pages/federation.vue +++ b/src/client/pages/federation.vue @@ -28,14 +28,14 @@ <option value="-following">{{ $ts.following }} ({{ $ts.ascendingOrder }})</option> <option value="+followers">{{ $ts.followers }} ({{ $ts.descendingOrder }})</option> <option value="-followers">{{ $ts.followers }} ({{ $ts.ascendingOrder }})</option> - <option value="+caughtAt">{{ $ts.caughtAt }} ({{ $ts.descendingOrder }})</option> - <option value="-caughtAt">{{ $ts.caughtAt }} ({{ $ts.ascendingOrder }})</option> - <option value="+lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.descendingOrder }})</option> - <option value="-lastCommunicatedAt">{{ $ts.lastCommunicatedAt }} ({{ $ts.ascendingOrder }})</option> + <option value="+caughtAt">{{ $ts.registeredAt }} ({{ $ts.descendingOrder }})</option> + <option value="-caughtAt">{{ $ts.registeredAt }} ({{ $ts.ascendingOrder }})</option> + <option value="+lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.descendingOrder }})</option> + <option value="-lastCommunicatedAt">{{ $ts.lastCommunication }} ({{ $ts.ascendingOrder }})</option> <option value="+driveUsage">{{ $ts.driveUsage }} ({{ $ts.descendingOrder }})</option> <option value="-driveUsage">{{ $ts.driveUsage }} ({{ $ts.ascendingOrder }})</option> - <option value="+driveFiles">{{ $ts.driveFiles }} ({{ $ts.descendingOrder }})</option> - <option value="-driveFiles">{{ $ts.driveFiles }} ({{ $ts.ascendingOrder }})</option> + <option value="+driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.descendingOrder }})</option> + <option value="-driveFiles">{{ $ts.driveFilesCount }} ({{ $ts.ascendingOrder }})</option> </MkSelect> </div> </div> diff --git a/src/client/pages/settings/general.vue b/src/client/pages/settings/general.vue index cfa8107d28..f8e8e6b24b 100644 --- a/src/client/pages/settings/general.vue +++ b/src/client/pages/settings/general.vue @@ -45,6 +45,10 @@ </FormSwitch> </FormGroup> + <FormGroup> + <FormSwitch v-model:value="aiChanMode">{{ $ts.aiChanMode }}</FormSwitch> + </FormGroup> + <FormRadios v-model="fontSize"> <template #desc>{{ $ts.fontSize }}</template> <option value="small"><span style="font-size: 14px;">Aa</span></option> @@ -149,6 +153,7 @@ export default defineComponent({ enableInfiniteScroll: defaultStore.makeGetterSetter('enableInfiniteScroll'), useReactionPickerForContextMenu: defaultStore.makeGetterSetter('useReactionPickerForContextMenu'), squareAvatars: defaultStore.makeGetterSetter('squareAvatars'), + aiChanMode: defaultStore.makeGetterSetter('aiChanMode'), }, watch: { @@ -184,6 +189,10 @@ export default defineComponent({ this.reloadAsk(); }, + aiChanMode() { + this.reloadAsk(); + }, + showGapBetweenNotesInTimeline() { this.reloadAsk(); }, diff --git a/src/client/pages/settings/privacy.vue b/src/client/pages/settings/privacy.vue index 4095e744c2..46d8c17ca2 100644 --- a/src/client/pages/settings/privacy.vue +++ b/src/client/pages/settings/privacy.vue @@ -28,6 +28,7 @@ </FormSelect> <FormSwitch v-model:value="defaultNoteLocalOnly">{{ $ts._visibility.localOnly }}</FormSwitch> </FormGroup> + <FormSwitch v-model:value="keepCw" @update:value="save()">{{ $ts.keepCw }}</FormSwitch> </FormBase> </template> @@ -69,6 +70,7 @@ export default defineComponent({ defaultNoteVisibility: defaultStore.makeGetterSetter('defaultNoteVisibility'), defaultNoteLocalOnly: defaultStore.makeGetterSetter('defaultNoteLocalOnly'), rememberNoteVisibility: defaultStore.makeGetterSetter('rememberNoteVisibility'), + keepCw: defaultStore.makeGetterSetter('keepCw'), }, created() { diff --git a/src/client/pages/welcome.setup.vue b/src/client/pages/welcome.setup.vue index de844ece1c..d0091bef67 100644 --- a/src/client/pages/welcome.setup.vue +++ b/src/client/pages/welcome.setup.vue @@ -53,7 +53,7 @@ export default defineComponent({ username: this.username, password: this.password, }).then(res => { - login(res.i); + return login(res.token); }).catch(() => { this.submitting = false; diff --git a/src/client/store.ts b/src/client/store.ts index 4c4a7d93e9..e4b762873d 100644 --- a/src/client/store.ts +++ b/src/client/store.ts @@ -210,6 +210,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: '' }, + aiChanMode: { + where: 'device', + default: false + }, })); // TODO: 他のタブと永続化されたstateを同期 diff --git a/src/client/style.scss b/src/client/style.scss index 269cf88939..6ab5e796bd 100644 --- a/src/client/style.scss +++ b/src/client/style.scss @@ -159,7 +159,6 @@ hr { display: inline-block; padding: 0; margin: 0; // for Safari - width: max-content; background: none; border: none; cursor: pointer; diff --git a/src/client/tsconfig.json b/src/client/tsconfig.json index ac7ef7ddfc..7a26047ddf 100644 --- a/src/client/tsconfig.json +++ b/src/client/tsconfig.json @@ -21,7 +21,8 @@ "baseUrl": ".", "paths": { "@/*": ["../*"], - "@client/*": ["./*"] + "@client/*": ["./*"], + "@lib/*": ["../../lib/*"], }, "typeRoots": [ "node_modules/@types", diff --git a/src/client/ui/default.vue b/src/client/ui/default.vue index 23b63114cc..eef693faef 100644 --- a/src/client/ui/default.vue +++ b/src/client/ui/default.vue @@ -54,12 +54,14 @@ <XWidgets v-if="widgetsShowing" class="tray"/> </transition> + <iframe v-if="$store.state.aiChanMode" class="ivnzpscs" ref="live2d" src="https://misskey-dev.github.io/mascot-web/?scale=2&y=1.4"></iframe> + <XCommon/> </div> </template> <script lang="ts"> -import { defineComponent, defineAsyncComponent } from 'vue'; +import { defineComponent, defineAsyncComponent, markRaw } from 'vue'; import { instanceName } from '@client/config'; import { StickySidebar } from '@client/scripts/sticky-sidebar'; import XSidebar from './default.sidebar.vue'; @@ -131,6 +133,19 @@ export default defineComponent({ this.isMobile = (window.innerWidth <= MOBILE_THRESHOLD); this.isDesktop = (window.innerWidth >= DESKTOP_THRESHOLD); }, { passive: true }); + + if (this.$store.state.aiChanMode) { + const iframeRect = this.$refs.live2d.getBoundingClientRect(); + window.addEventListener('mousemove', ev => { + this.$refs.live2d.contentWindow.postMessage({ + type: 'moveCursor', + body: { + x: ev.clientX - iframeRect.left, + y: ev.clientY - iframeRect.top, + } + }, '*'); + }, { passive: true }); + } }, methods: { @@ -201,6 +216,10 @@ export default defineComponent({ } }], e); }, + + onAiClick(ev) { + //if (this.live2d) this.live2d.click(ev); + } } }); </script> @@ -458,5 +477,15 @@ export default defineComponent({ overflow: auto; background: var(--bg); } + + > .ivnzpscs { + position: fixed; + bottom: 0; + right: 0; + width: 300px; + height: 600px; + border: none; + pointer-events: none; + } } </style> diff --git a/src/client/widgets/aichan.vue b/src/client/widgets/aichan.vue new file mode 100644 index 0000000000..06c49090a1 --- /dev/null +++ b/src/client/widgets/aichan.vue @@ -0,0 +1,59 @@ +<template> +<MkContainer :naked="props.transparent" :show-header="false"> + <iframe class="dedjhjmo" ref="live2d" @click="touched" src="https://misskey-dev.github.io/mascot-web/?scale=1.5&y=1.1&eyeY=100"></iframe> +</MkContainer> +</template> + +<script lang="ts"> +import { defineComponent, markRaw } from 'vue'; +import define from './define'; +import MkContainer from '@client/components/ui/container.vue'; +import * as os from '@client/os'; + +const widget = define({ + name: 'ai', + props: () => ({ + transparent: { + type: 'boolean', + default: false, + }, + }) +}); + +export default defineComponent({ + extends: widget, + components: { + MkContainer, + }, + data() { + return { + }; + }, + mounted() { + window.addEventListener('mousemove', ev => { + const iframeRect = this.$refs.live2d.getBoundingClientRect(); + this.$refs.live2d.contentWindow.postMessage({ + type: 'moveCursor', + body: { + x: ev.clientX - iframeRect.left, + y: ev.clientY - iframeRect.top, + } + }, '*'); + }, { passive: true }); + }, + methods: { + touched() { + //if (this.live2d) this.live2d.changeExpression('gurugurume'); + } + } +}); +</script> + +<style lang="scss" scoped> +.dedjhjmo { + width: 100%; + height: 350px; + border: none; + pointer-events: none; +} +</style> diff --git a/src/client/widgets/index.ts b/src/client/widgets/index.ts index 38cb85494a..51a82af080 100644 --- a/src/client/widgets/index.ts +++ b/src/client/widgets/index.ts @@ -19,6 +19,7 @@ export default function(app: App) { app.component('MkwJobQueue', defineAsyncComponent(() => import('./job-queue.vue'))); app.component('MkwButton', defineAsyncComponent(() => import('./button.vue'))); app.component('MkwAiscript', defineAsyncComponent(() => import('./aiscript.vue'))); + app.component('MkwAichan', defineAsyncComponent(() => import('./aichan.vue'))); } export const widgets = [ @@ -40,4 +41,5 @@ export const widgets = [ 'jobQueue', 'button', 'aiscript', + 'aichan', ]; |