Compare commits

...

2 Commits

Author SHA1 Message Date
ThatOneCalculator 782a8e9f79
refactor: max 5 url previews
Closes #9654
2023-02-20 11:51:15 -08:00
ThatOneCalculator 800cb7da45
new swiper 2023-02-18 20:28:10 -08:00
15 changed files with 169 additions and 77 deletions

View File

@ -34,9 +34,9 @@
"calckey-js": "^0.0.22",
"chart.js": "4.1.1",
"chartjs-adapter-date-fns": "2.0.1",
"chartjs-chart-matrix": "^2.0.1",
"chartjs-plugin-gradient": "0.5.1",
"chartjs-plugin-zoom": "1.2.1",
"chartjs-chart-matrix": "^2.0.1",
"city-timezones": "^1.2.1",
"compare-versions": "5.0.3",
"cropperjs": "2.0.0-beta.2",
@ -46,6 +46,7 @@
"escape-regexp": "0.0.1",
"eventemitter3": "4.0.7",
"gsap": "^3.11.4",
"hammerjs": "^2.0.8",
"idb-keyval": "6.2.0",
"insert-text-at-cursor": "0.3.0",
"json5": "2.2.3",
@ -64,7 +65,6 @@
"start-server-and-test": "1.15.2",
"strict-event-emitter-types": "2.0.0",
"stringz": "2.1.0",
"swiper": "^8.4.5",
"syuilo-password-strength": "0.0.1",
"textarea-caret": "3.1.0",
"three": "0.146.0",

View File

@ -60,7 +60,7 @@
<XMediaList :media-list="appearNote.files"/>
</div>
<XPoll v-if="appearNote.poll" ref="pollViewer" :note="appearNote" class="poll"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" class="url-preview"/>
<MkUrlPreview v-for="url in urls.slice(0, 5)" :key="url" :url="url" :compact="true" :detail="false" class="url-preview"/>
<div v-if="appearNote.renote" class="renote"><XNoteSimple :note="appearNote.renote"/></div>
<button v-if="isLong && collapsed" class="fade _button" @click.stop.prevent="collapsed = false">
<span>{{ i18n.ts.showMore }}</span>

View File

@ -67,7 +67,7 @@
<XMediaList :media-list="appearNote.files"/>
</div>
<XPoll v-if="appearNote.poll" ref="pollViewer" :note="appearNote" class="poll"/>
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" class="url-preview"/>
<MkUrlPreview v-for="url in urls.slice(0, 5)" :key="url" :url="url" :compact="true" :detail="true" class="url-preview"/>
<div v-if="appearNote.renote" class="renote"><XNoteSimple :note="appearNote.renote"/></div>
</div>
<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="ph-television-bold ph-lg"></i> {{ appearNote.channel.name }}</MkA>

View File

@ -0,0 +1,125 @@
<template>
<div class="swipeable-views" ref="swipeableViews">
<div class="swipeable-view" :class="{ 'active': state.index === i }" v-for="(view, i) in props.views" :key="i" ref="view-{{i}}">
<slot :name="view.name" :data="view.data"></slot>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted } from 'vue';
import Hammer from 'hammerjs';
interface View {
name: string;
data: any;
}
interface State {
index: number;
direction: number | null;
nextIndex: number | null;
prevIndex: number | null;
}
const refs = {
swipeableViews: ref<HTMLElement | null>(null),
};
const props = defineProps({
views: {
type: Array as () => View[],
required: true,
default: () => [],
},
activeIndex: {
type: Number,
default: 0,
},
});
const state = reactive<State>({
index: props.activeIndex,
direction: null,
nextIndex: null,
prevIndex: null,
});
const moveView = () => {
if (state.direction !== null) {
const newIndex = state.index + state.direction;
if (newIndex >= 0 && newIndex < props.views.length && newIndex !== state.index) {
state.nextIndex = state.direction === 1 ? newIndex : null;
state.prevIndex = state.direction === -1 ? newIndex : null;
const { swipeableViews } = refs;
const activeView = swipeableViews.value?.children[state.index];
const newView = swipeableViews.value?.children[newIndex];
const translateX = state.direction === 1 ? '-100%' : '100%';
Object.assign(newView.style, { transform: `translateX(${translateX})` });
Object.assign(newView.classList, { active: true, next: state.direction === 1, prev: state.direction === -1 });
Object.assign(activeView.classList, { next: state.direction === 1, prev: state.direction === -1 });
state.index = newIndex;
setTimeout(() => {
Object.assign(newView.style, { transform: 'translateX(0)' });
Object.assign(activeView.style, { transform: `translateX(${translateX})` });
}, 0);
setTimeout(() => {
Object.assign(activeView.classList, { active: false, prev: false, next: false });
Object.assign(newView.classList, { prev: false, next: false });
Object.assign(activeView.style, { transform: '' });
state.nextIndex = null;
state.prevIndex = null;
}, 300);
}
state.direction = null;
}
};
// Move to script later
function setView (viewIndex: number) {
if (viewIndex !== state.index) {
state.direction = viewIndex > state.index ? 1 : -1;
moveView();
}
};
onMounted(() => {
const swipeableViews = refs.swipeableViews!.value!;
const hammer = new Hammer(swipeableViews);
hammer.get('swipe').set({ direction: Hammer.DIRECTION_HORIZONTAL });
hammer.on('swipeleft swiperight', (event) => {
state.direction = event.type === 'swipeleft' ? 1 : -1;
moveView();
});
});
</script>
<style lang="scss" scoped>
.swipeable-views {
display: flex;
overflow-x: hidden;
width: 100%;
}
.swipeable-view {
flex: 1;
width: 100%;
height: 100%;
transition: transform 0.3s ease-in-out;
transform: translateX(0);
}
.swipeable-view.active {
transform: translateX(0);
}
.swipeable-view.next {
transform: translateX(100%);
}
.swipeable-view.prev {
transform: translateX(-100%);
}
</style>

View File

@ -92,8 +92,7 @@
<script lang="ts" setup>
import { ref, computed, onMounted, watch } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import XEmojis from './about.emojis.vue';
import XFederation from './about.federation.vue';
import { version, instanceName , host } from '@/config';
@ -111,8 +110,7 @@ import { deviceKind } from '@/scripts/device-kind';
import { iAmModerator } from '@/account';
import { instance } from '@/instance';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
withDefaults(defineProps<{
initialTab?: string;

View File

@ -78,8 +78,7 @@
<script lang="ts" setup>
import { computed, watch } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import MkButton from '@/components/MkButton.vue';
import MkSwitch from '@/components/form/switch.vue';
import MkObjectView from '@/components/MkObjectView.vue';
@ -96,8 +95,7 @@ import { deviceKind } from '@/scripts/device-kind';
import { acct } from '@/filters/user';
import { iAmAdmin, iAmModerator } from '@/account';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
let tabs = ['overview'];
if (iAmModerator) tabs.push('ip');

View File

@ -39,8 +39,7 @@
<script lang="ts" setup>
import { computed, defineComponent, inject, watch } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import MkChannelPreview from '@/components/MkChannelPreview.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkButton from '@/components/MkButton.vue';
@ -49,8 +48,7 @@ import { definePageMetadata } from '@/scripts/page-metadata';
import { deviceKind } from '@/scripts/device-kind';
import { i18n } from '@/i18n';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
const router = useRouter();

View File

@ -39,8 +39,7 @@
<script lang="ts" setup>
import { computed, watch, onMounted } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import XFeatured from './explore.featured.vue';
import XUsers from './explore.users.vue';
import type MkFolder from '@/components/MkFolder.vue';
@ -51,8 +50,7 @@ import { deviceKind } from '@/scripts/device-kind';
import { i18n } from '@/i18n';
import XUserList from '@/components/MkUserList.vue';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
const props = defineProps<{
tag?: string;

View File

@ -50,8 +50,7 @@
<script lang="ts" setup>
import { computed, defineComponent, watch, onMounted } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import MkFolder from '@/components/MkFolder.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkGalleryPostPreview from '@/components/MkGalleryPostPreview.vue';
@ -60,8 +59,7 @@ import { deviceKind } from '@/scripts/device-kind';
import { i18n } from '@/i18n';
import { useRouter } from '@/router';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
const router = useRouter();

View File

@ -133,8 +133,7 @@
<script lang="ts" setup>
import { watch } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import type * as misskey from 'calckey-js';
import MkChart from '@/components/MkChart.vue';
import MkObjectView from '@/components/MkObjectView.vue';
@ -154,8 +153,7 @@ import { defaultStore } from '@/store';
import { i18n } from '@/i18n';
import MkUserCardMini from '@/components/MkUserCardMini.vue';
import MkPagination from '@/components/MkPagination.vue';
import 'swiper/scss';
import 'swiper/scss/virtual';
import { getProxiedImageUrlNullable } from '@/scripts/media-proxy';
const props = defineProps<{

View File

@ -39,8 +39,7 @@
<script lang="ts" setup>
import { markRaw, onMounted, onUnmounted, watch } from 'vue';
import * as Acct from 'calckey-js/built/acct';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import MkButton from '@/components/MkButton.vue';
import MkChatPreview from '@/components/MkChatPreview.vue';
import MkPagination from '@/components/MkPagination.vue';
@ -52,8 +51,7 @@ import { definePageMetadata } from '@/scripts/page-metadata';
import { $i } from '@/account';
import { deviceKind } from '@/scripts/device-kind';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
const router = useRouter();

View File

@ -36,8 +36,7 @@
<script lang="ts" setup>
import { computed, ref, watch } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import { notificationTypes } from 'calckey-js';
import XNotifications from '@/components/MkNotifications.vue';
import XNotes from '@/components/MkNotes.vue';
@ -46,8 +45,7 @@ import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
import { deviceKind } from '@/scripts/device-kind';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
const tabs = ['all', 'unread', 'mentions', 'directNotes'];
let tab = $ref(tabs[0]);

View File

@ -41,8 +41,7 @@
<script lang="ts" setup>
import { computed, watch, onMounted } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import MkPagePreview from '@/components/MkPagePreview.vue';
import MkPagination from '@/components/MkPagination.vue';
import MkButton from '@/components/MkButton.vue';
@ -51,8 +50,7 @@ import { i18n } from '@/i18n';
import { definePageMetadata } from '@/scripts/page-metadata';
import { deviceKind } from '@/scripts/device-kind';
import { defaultStore } from '@/store';
import 'swiper/scss';
import 'swiper/scss/virtual';
const router = useRouter();

View File

@ -32,15 +32,8 @@
/>
</div> *v-else on next div* -->
<div class="tl _block">
<swiper
:modules="[Virtual]"
:space-between="20"
:virtual="true"
:allow-touch-move="!(deviceKind === 'desktop' && !defaultStore.state.swipeOnDesktop)"
@swiper="setSwiperRef"
@slide-change="onSlideChange"
>
<swiper-slide
<MkSwiper :views="timelines">
<template
v-for="index in timelines"
:key="index"
:virtual-index="index"
@ -53,8 +46,8 @@
:sound="true"
@queue="queueUpdated"
/>
</swiper-slide>
</swiper>
</template>
</MkSwiper>
</div>
</div>
</MkSpacer>
@ -63,8 +56,7 @@
<script lang="ts" setup>
import { computed, watch, ref, onMounted } from 'vue';
import { Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/vue';
import MkSwiper from '@/components/MkSwiper.vue';
import XTutorial from '@/components/MkTutorialDialog.vue';
import XTimeline from '@/components/MkTimeline.vue';
import XPostForm from '@/components/MkPostForm.vue';
@ -76,8 +68,7 @@ import { instance } from '@/instance';
import { $i } from '@/account';
import { definePageMetadata } from '@/scripts/page-metadata';
import { deviceKind } from '@/scripts/device-kind';
import 'swiper/scss';
import 'swiper/scss/virtual';
if (defaultStore.reactiveState.tutorial.value !== -1) {
os.popup(XTutorial, {}, {}, 'closed');

View File

@ -429,6 +429,7 @@ importers:
escape-regexp: 0.0.1
eventemitter3: 4.0.7
gsap: ^3.11.4
hammerjs: ^2.0.8
idb-keyval: 6.2.0
insert-text-at-cursor: 0.3.0
json5: 2.2.3
@ -447,7 +448,6 @@ importers:
start-server-and-test: 1.15.2
strict-event-emitter-types: 2.0.0
stringz: 2.1.0
swiper: ^8.4.5
syuilo-password-strength: 0.0.1
textarea-caret: 3.1.0
three: 0.146.0
@ -505,6 +505,7 @@ importers:
escape-regexp: 0.0.1
eventemitter3: 4.0.7
gsap: 3.11.4
hammerjs: 2.0.8
idb-keyval: 6.2.0
insert-text-at-cursor: 0.3.0
json5: 2.2.3
@ -523,7 +524,6 @@ importers:
start-server-and-test: 1.15.2
strict-event-emitter-types: 2.0.0
stringz: 2.1.0
swiper: 8.4.5
syuilo-password-strength: 0.0.1
textarea-caret: 3.1.0
three: 0.146.0
@ -3392,7 +3392,7 @@ packages:
/axios/0.25.0_debug@4.3.4:
resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==}
dependencies:
follow-redirects: 1.15.2
follow-redirects: 1.15.2_debug@4.3.4
transitivePeerDependencies:
- debug
dev: true
@ -5437,12 +5437,6 @@ packages:
domhandler: 5.0.3
entities: 4.4.0
/dom7/4.0.4:
resolution: {integrity: sha512-DSSgBzQ4rJWQp1u6o+3FVwMNnT5bzQbMb+o31TjYYeRi05uAcpF8koxdfzeoe5ElzPmua7W7N28YJhF7iEKqIw==}
dependencies:
ssr-window: 4.0.2
dev: true
/domelementtype/1.3.1:
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
dev: false
@ -6391,6 +6385,19 @@ packages:
peerDependenciesMeta:
debug:
optional: true
dev: false
/follow-redirects/1.15.2_debug@4.3.4:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dependencies:
debug: 4.3.4
dev: true
/for-each/0.3.3:
resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==}
@ -11694,10 +11701,6 @@ packages:
safer-buffer: 2.1.2
tweetnacl: 0.14.5
/ssr-window/4.0.2:
resolution: {integrity: sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==}
dev: true
/ssri/9.0.1:
resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@ -11978,15 +11981,6 @@ packages:
webpack: 5.75.0_@swc+core@1.3.26
dev: true
/swiper/8.4.5:
resolution: {integrity: sha512-zveyEFBBv4q1sVkbJHnuH4xCtarKieavJ4SxP0QEHvdpPLJRuD7j/Xg38IVVLbp7Db6qrPsLUePvxohYx39Agw==}
engines: {node: '>= 4.7.0'}
requiresBuild: true
dependencies:
dom7: 4.0.4
ssr-window: 4.0.2
dev: true
/symbol-tree/3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
dev: false