feat: ✨ Swipe through timelines on mobile
This commit is contained in:
parent
8068d9ed92
commit
c383c30e80
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"version": "12.118.1-calc.2",
|
"version": "12.118.1-calc.2",
|
||||||
"codename": "aqua",
|
"codename": "aqua",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -51,7 +51,8 @@
|
||||||
"gulp-terser": "2.1.0",
|
"gulp-terser": "2.1.0",
|
||||||
"js-yaml": "4.1.0",
|
"js-yaml": "4.1.0",
|
||||||
"long": "^5.2.0",
|
"long": "^5.2.0",
|
||||||
"seedrandom": "^3.0.5"
|
"seedrandom": "^3.0.5",
|
||||||
|
"tocada": "^1.0.0-beta.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/gulp": "4.0.9",
|
"@types/gulp": "4.0.9",
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { defineAsyncComponent, computed, watch } from 'vue';
|
import { defineAsyncComponent, computed, watch, ref } from 'vue';
|
||||||
import XTimeline from '@/components/timeline.vue';
|
import XTimeline from '@/components/timeline.vue';
|
||||||
import XPostForm from '@/components/post-form.vue';
|
import XPostForm from '@/components/post-form.vue';
|
||||||
import { scroll } from '@/scripts/scroll';
|
import { scroll } from '@/scripts/scroll';
|
||||||
|
@ -32,6 +32,9 @@ import { i18n } from '@/i18n';
|
||||||
import { instance } from '@/instance';
|
import { instance } from '@/instance';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
|
import { deviceKind } from '@/scripts/device-kind';
|
||||||
|
|
||||||
|
import 'tocada';
|
||||||
|
|
||||||
const XTutorial = defineAsyncComponent(() => import('./timeline.tutorial.vue'));
|
const XTutorial = defineAsyncComponent(() => import('./timeline.tutorial.vue'));
|
||||||
|
|
||||||
|
@ -43,6 +46,16 @@ const keymap = {
|
||||||
't': focus,
|
't': focus,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DESKTOP_THRESHOLD = 1100;
|
||||||
|
const MOBILE_THRESHOLD = 500;
|
||||||
|
|
||||||
|
// デスクトップでウィンドウを狭くしたときモバイルUIが表示されて欲しいことはあるので deviceKind === 'desktop' の判定は行わない
|
||||||
|
const isDesktop = ref(window.innerWidth >= DESKTOP_THRESHOLD);
|
||||||
|
const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);
|
||||||
|
window.addEventListener('resize', () => {
|
||||||
|
isMobile.value = deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD;
|
||||||
|
});
|
||||||
|
|
||||||
const tlComponent = $ref<InstanceType<typeof XTimeline>>();
|
const tlComponent = $ref<InstanceType<typeof XTimeline>>();
|
||||||
const rootEl = $ref<HTMLElement>();
|
const rootEl = $ref<HTMLElement>();
|
||||||
|
|
||||||
|
@ -91,7 +104,7 @@ async function chooseChannel(ev: MouseEvent): Promise<void> {
|
||||||
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
os.popupMenu(items, ev.currentTarget ?? ev.target);
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSrc(newSrc: 'home' | 'local' | 'social' | 'global'): void {
|
function saveSrc(newSrc: 'home' | 'local' | 'recommended' | 'social' | 'global'): void {
|
||||||
defaultStore.set('tl', {
|
defaultStore.set('tl', {
|
||||||
...defaultStore.state.tl,
|
...defaultStore.state.tl,
|
||||||
src: newSrc,
|
src: newSrc,
|
||||||
|
@ -162,6 +175,20 @@ definePageMetadata(computed(() => ({
|
||||||
title: i18n.ts.timeline,
|
title: i18n.ts.timeline,
|
||||||
icon: src === 'local' ? 'fas fa-user-group' : src === 'social' ? 'fas fa-handshake-simple' : src === 'recommended' ? 'fas fa-signs-post' : src === 'global' ? 'fas fa-globe' : 'fas fa-home',
|
icon: src === 'local' ? 'fas fa-user-group' : src === 'social' ? 'fas fa-handshake-simple' : src === 'recommended' ? 'fas fa-signs-post' : src === 'global' ? 'fas fa-globe' : 'fas fa-home',
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
if (isMobile.value) {
|
||||||
|
window.addEventListener('swipeleft', () => {
|
||||||
|
const current = headerTabs.value.find(x => x.key === src.value);
|
||||||
|
const next = headerTabs.value[(headerTabs.value.indexOf(current) - 1) % headerTabs.value.length];
|
||||||
|
saveSrc(next.key);
|
||||||
|
});
|
||||||
|
window.addEventListener('swiperight', () => {
|
||||||
|
const current = headerTabs.value.find(x => x.key === src.value);
|
||||||
|
const next = headerTabs.value[(headerTabs.value.indexOf(current) + 1) % headerTabs.value.length];
|
||||||
|
saveSrc(next.key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<MkStickyContainer class="contents">
|
<MkStickyContainer class="contents">
|
||||||
<template #header><XStatusBars :class="$style.statusbars"/></template>
|
<template #header><XStatusBars :class="$style.statusbars"/></template>
|
||||||
<main style="min-width: 0;" :style="{ background: pageMetadata?.value?.bg }" @contextmenu.stop="onContextmenu">
|
<main id="maincontent" style="min-width: 0;" :style="{ background: pageMetadata?.value?.bg }" @contextmenu.stop="onContextmenu">
|
||||||
<div :class="$style.content">
|
<div :class="$style.content">
|
||||||
<RouterView/>
|
<RouterView/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -71,6 +71,7 @@ import { Router } from '@/nirax';
|
||||||
import { mainRouter } from '@/router';
|
import { mainRouter } from '@/router';
|
||||||
import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata';
|
import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata';
|
||||||
import { deviceKind } from '@/scripts/device-kind';
|
import { deviceKind } from '@/scripts/device-kind';
|
||||||
|
|
||||||
const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
|
const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue'));
|
||||||
const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/navbar.vue'));
|
const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/navbar.vue'));
|
||||||
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
|
const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue'));
|
||||||
|
@ -170,6 +171,7 @@ function top() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const wallpaper = localStorage.getItem('wallpaper') != null;
|
const wallpaper = localStorage.getItem('wallpaper') != null;
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -288,14 +290,11 @@ const wallpaper = localStorage.getItem('wallpaper') != null;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
padding: 16px 16px calc(env(safe-area-inset-bottom, 0px) + 16px) 16px;
|
padding: 12px 12px calc(env(safe-area-inset-bottom, 0px) + 12px) 12px;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-backdrop-filter: var(--blur, blur(32px));
|
background-color: var(--bg);
|
||||||
backdrop-filter: var(--blur, blur(32px));
|
|
||||||
background-color: var(--header);
|
|
||||||
border-top: solid 0.5px var(--divider);
|
|
||||||
|
|
||||||
> .button {
|
> .button {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -341,7 +340,7 @@ const wallpaper = localStorage.getItem('wallpaper') != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
font-size: 20px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -3236,7 +3236,7 @@ __metadata:
|
||||||
"browser-image-resizer@git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.2":
|
"browser-image-resizer@git+https://github.com/misskey-dev/browser-image-resizer#v2.2.1-misskey.2":
|
||||||
version: 2.2.1-misskey.2
|
version: 2.2.1-misskey.2
|
||||||
resolution: "browser-image-resizer@https://github.com/misskey-dev/browser-image-resizer.git#commit=a58834f5fe2af9f9f31ff115121aef3de6f9d416"
|
resolution: "browser-image-resizer@https://github.com/misskey-dev/browser-image-resizer.git#commit=a58834f5fe2af9f9f31ff115121aef3de6f9d416"
|
||||||
checksum: eb5ddfe7f6a2de96340ef420df9be03a75f2bfd8f568a60be22cc8f2ccdcb754105b7799cf706c09add3f9d82b7ce1c6f963842f80a85f234b26ef6bf1b8da09
|
checksum: 8ea30705704cc3f81eca23ff6cd0d5bf0d5404cd82612a52de11c0b851be511613022758babf5c202cc92b019483cfb97d7ef48cc18368a8913803fd654ac5d1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -10101,6 +10101,7 @@ __metadata:
|
||||||
long: ^5.2.0
|
long: ^5.2.0
|
||||||
seedrandom: ^3.0.5
|
seedrandom: ^3.0.5
|
||||||
start-server-and-test: 1.14.0
|
start-server-and-test: 1.14.0
|
||||||
|
tocada: ^1.0.0-beta.6
|
||||||
typescript: 4.7.4
|
typescript: 4.7.4
|
||||||
vue-eslint-parser: ^9.0.2
|
vue-eslint-parser: ^9.0.2
|
||||||
languageName: unknown
|
languageName: unknown
|
||||||
|
@ -14374,6 +14375,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"tocada@npm:^1.0.0-beta.6":
|
||||||
|
version: 1.0.0-beta.6
|
||||||
|
resolution: "tocada@npm:1.0.0-beta.6"
|
||||||
|
checksum: 62637d2a5ca96b592cb0aa95d1e474386b95ac52111da90a0a9348b73f5f27633fef95222b0c8ff2f6c2767dabea0a3182ea1d4d6454ef02e03efe3a364d18c7
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"toidentifier@npm:1.0.1":
|
"toidentifier@npm:1.0.1":
|
||||||
version: 1.0.1
|
version: 1.0.1
|
||||||
resolution: "toidentifier@npm:1.0.1"
|
resolution: "toidentifier@npm:1.0.1"
|
||||||
|
@ -14783,7 +14791,7 @@ __metadata:
|
||||||
|
|
||||||
"typescript@patch:typescript@4.7.4#~builtin<compat/typescript>":
|
"typescript@patch:typescript@4.7.4#~builtin<compat/typescript>":
|
||||||
version: 4.7.4
|
version: 4.7.4
|
||||||
resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin<compat/typescript>::version=4.7.4&hash=7ad353"
|
resolution: "typescript@patch:typescript@npm%3A4.7.4#~builtin<compat/typescript>::version=4.7.4&hash=f456af"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
|
|
Loading…
Reference in New Issue