1
1
mirror of https://github.com/kokonect-link/cherrypick synced 2024-11-23 22:56:53 +09:00

Merge remote-pull-request 'misskey-dev#10934'

This commit is contained in:
NoriDev 2023-06-10 21:03:50 +09:00
commit 2ce329a1a9
5 changed files with 208 additions and 23 deletions

View File

@ -15,6 +15,7 @@
## 13.13.1 (unreleased)
### Client
- フォロー/フォロワーを非公開としている場合、表示は「0」ではなく鍵アイコンを表示するように
- Fix: タブがアクティブな間はstreamが切断されないように
### General

View File

@ -17,12 +17,22 @@
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.notes }}</p><span :class="$style.statusItemValue">{{ user.notesCount }}</span>
</div>
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.following }}</p><span :class="$style.statusItemValue">{{ user.followingCount }}</span>
</div>
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.followers }}</p><span :class="$style.statusItemValue">{{ user.followersCount }}</span>
</div>
<template v-if="isFfVisibility($i, props.user)">
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.following }}</p><span :class="$style.statusItemValue">{{ user.followingCount }}</span>
</div>
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.followers }}</p><span :class="$style.statusItemValue">{{ user.followersCount }}</span>
</div>
</template>
<template v-else>
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.following }}</p><span :class="$style.statusItemValue"><i class="ti ti-lock" :class="[$style.keyWiggleArea, { [$style.animation]: animation }]"></i></span>
</div>
<div :class="$style.statusItem">
<p :class="$style.statusItemLabel">{{ i18n.ts.followers }}</p><span :class="$style.statusItemValue"><i class="ti ti-lock" :class="[$style.keyWiggleArea, { [$style.animation]: animation }]"></i></span>
</div>
</template>
</div>
<MkFollowButton v-if="$i && user.id != $i.id" :class="$style.follow" :user="user" mini/>
</div>
@ -34,10 +44,14 @@ import MkFollowButton from '@/components/MkFollowButton.vue';
import { userPage } from '@/filters/user';
import { i18n } from '@/i18n';
import { $i } from '@/account';
import { isFfVisibility } from '@/scripts/is-ff-visibility';
import { defaultStore } from '@/store';
defineProps<{
const props = defineProps<{
user: misskey.entities.UserDetailed;
}>();
const animation = $ref(defaultStore.state.animation);
</script>
<style lang="scss" module>
@ -135,4 +149,36 @@ defineProps<{
top: 8px;
right: 8px;
}
.keyWiggleArea {
display: block;
}
@keyframes keywiggle {
0% { transform: translate(-3px,-1px) rotate(-8deg); }
5% { transform: translateY(-1px) rotate(-10deg); }
10% { transform: translate(1px,-3px) rotate(0); }
15% { transform: translate(1px,1px) rotate(11deg); }
20% { transform: translate(-2px,1px) rotate(1deg); }
25% { transform: translate(-1px,-2px) rotate(-2deg); }
30% { transform: translate(-1px,2px) rotate(-3deg); }
35% { transform: translate(2px,1px) rotate(6deg); }
40% { transform: translate(-2px,-3px) rotate(-9deg); }
45% { transform: translateY(-1px) rotate(-12deg); }
50% { transform: translate(1px,2px) rotate(10deg); }
55% { transform: translateY(-3px) rotate(8deg); }
60% { transform: translate(1px,-1px) rotate(8deg); }
65% { transform: translateY(-1px) rotate(-7deg); }
70% { transform: translate(-1px,-3px) rotate(6deg); }
75% { transform: translateY(-2px) rotate(4deg); }
80% { transform: translate(-2px,-1px) rotate(3deg); }
85% { transform: translate(1px,-3px) rotate(-10deg); }
90% { transform: translate(1px) rotate(3deg); }
95% { transform: translate(-2px) rotate(-3deg); }
to { transform: translate(2px,1px) rotate(2deg); }
}
.animation:hover {
animation: keywiggle 1s;
}
</style>

View File

@ -30,14 +30,26 @@
<div :class="$style.statusItemLabel">{{ i18n.ts.notes }}</div>
<div>{{ number(user.notesCount) }}</div>
</div>
<div :class="$style.statusItem">
<div :class="$style.statusItemLabel">{{ i18n.ts.following }}</div>
<div>{{ number(user.followingCount) }}</div>
</div>
<div :class="$style.statusItem">
<div :class="$style.statusItemLabel">{{ i18n.ts.followers }}</div>
<div>{{ number(user.followersCount) }}</div>
</div>
<template v-if="isFfVisibility($i, user)">
<div :class="$style.statusItem">
<div :class="$style.statusItemLabel">{{ i18n.ts.following }}</div>
<div>{{ number(user.followingCount) }}</div>
</div>
<div :class="$style.statusItem">
<div :class="$style.statusItemLabel">{{ i18n.ts.followers }}</div>
<div>{{ number(user.followersCount) }}</div>
</div>
</template>
<template v-else>
<div :class="$style.statusItem">
<div :class="$style.statusItemLabel">{{ i18n.ts.following }}</div>
<div><i class="ti ti-lock" :class="[$style.keyWiggleArea, { [$style.animation]: animation }]"></i></div>
</div>
<div :class="$style.statusItem">
<div :class="$style.statusItemLabel">{{ i18n.ts.followers }}</div>
<div><i class="ti ti-lock" :class="[$style.keyWiggleArea, { [$style.animation]: animation }]"></i></div>
</div>
</template>
</div>
<button class="_button" :class="$style.menu" @click="showMenu"><i class="ti ti-dots"></i></button>
<MkFollowButton v-if="$i && user.id != $i.id" :class="$style.follow" :user="user" mini/>
@ -61,6 +73,7 @@ import number from '@/filters/number';
import { i18n } from '@/i18n';
import { defaultStore } from '@/store';
import { $i } from '@/account';
import { isFfVisibility } from '@/scripts/is-ff-visibility';
const props = defineProps<{
showing: boolean;
@ -75,6 +88,9 @@ const emit = defineEmits<{
}>();
const zIndex = os.claimZIndex('middle');
const animation = $ref(defaultStore.state.animation);
let user = $ref<misskey.entities.UserDetailed | null>(null);
let top = $ref(0);
let left = $ref(0);
@ -228,4 +244,37 @@ onMounted(() => {
top: 8px;
right: 8px;
}
.keyWiggleArea {
display: block;
margin: 0 auto;
}
@keyframes keywiggle {
0% { transform: translate(-3px,-1px) rotate(-8deg); }
5% { transform: translateY(-1px) rotate(-10deg); }
10% { transform: translate(1px,-3px) rotate(0); }
15% { transform: translate(1px,1px) rotate(11deg); }
20% { transform: translate(-2px,1px) rotate(1deg); }
25% { transform: translate(-1px,-2px) rotate(-2deg); }
30% { transform: translate(-1px,2px) rotate(-3deg); }
35% { transform: translate(2px,1px) rotate(6deg); }
40% { transform: translate(-2px,-3px) rotate(-9deg); }
45% { transform: translateY(-1px) rotate(-12deg); }
50% { transform: translate(1px,2px) rotate(10deg); }
55% { transform: translateY(-3px) rotate(8deg); }
60% { transform: translate(1px,-1px) rotate(8deg); }
65% { transform: translateY(-1px) rotate(-7deg); }
70% { transform: translate(-1px,-3px) rotate(6deg); }
75% { transform: translateY(-2px) rotate(4deg); }
80% { transform: translate(-2px,-1px) rotate(3deg); }
85% { transform: translate(1px,-3px) rotate(-10deg); }
90% { transform: translate(1px) rotate(3deg); }
95% { transform: translate(-2px) rotate(-3deg); }
to { transform: translate(2px,1px) rotate(2deg); }
}
.animation:hover {
animation: keywiggle 1s;
}
</style>

View File

@ -102,14 +102,26 @@
<b>{{ number(user.notesCount) }}</b>
<span>{{ i18n.ts.notes }}</span>
</MkA>
<MkA v-click-anime :to="userPage(user, 'following')">
<b>{{ number(user.followingCount) }}</b>
<span>{{ i18n.ts.following }}</span>
</MkA>
<MkA v-click-anime :to="userPage(user, 'followers')">
<b>{{ number(user.followersCount) }}</b>
<span>{{ i18n.ts.followers }}</span>
</MkA>
<template v-if="isFfVisibility($i, props.user)">
<MkA v-click-anime :to="userPage(user, 'following')">
<b>{{ number(user.followingCount) }}</b>
<span>{{ i18n.ts.following }}</span>
</MkA>
<MkA v-click-anime :to="userPage(user, 'followers')">
<b>{{ number(user.followersCount) }}</b>
<span>{{ i18n.ts.followers }}</span>
</MkA>
</template>
<template v-else>
<div>
<i class="ti ti-lock" :class="{ [$style.animation]: animation }"></i>
<span>{{ i18n.ts.following }}</span>
</div>
<div>
<i class="ti ti-lock" :class="{ [$style.animation]: animation }"></i>
<span>{{ i18n.ts.followers }}</span>
</div>
</template>
</div>
</div>
</div>
@ -158,6 +170,8 @@ import { dateString } from '@/filters/date';
import { confetti } from '@/scripts/confetti';
import MkNotes from '@/components/MkNotes.vue';
import { api } from '@/os';
import { isFfVisibility } from '@/scripts/is-ff-visibility';
import { defaultStore } from '@/store';
const XPhotos = defineAsyncComponent(() => import('./index.photos.vue'));
const XActivity = defineAsyncComponent(() => import('./index.activity.vue'));
@ -205,6 +219,8 @@ const age = $computed(() => {
return calcAge(props.user.birthday);
});
const animation = $ref(defaultStore.state.animation);
function menu(ev) {
os.popupMenu(getUserMenu(props.user, router), ev.currentTarget ?? ev.target);
}
@ -551,6 +567,21 @@ onUnmounted(() => {
font-size: 70%;
}
}
>div {
flex: 1;
text-align: center;
> i {
display: block;
line-height: 16px;
margin: 0 auto;
}
> span {
font-size: 70%;
}
}
}
}
}
@ -651,4 +682,32 @@ onUnmounted(() => {
border-radius: var(--radius);
overflow: clip;
}
@keyframes keywiggle {
0% { transform: translate(-3px,-1px) rotate(-8deg); }
5% { transform: translateY(-1px) rotate(-10deg); }
10% { transform: translate(1px,-3px) rotate(0); }
15% { transform: translate(1px,1px) rotate(11deg); }
20% { transform: translate(-2px,1px) rotate(1deg); }
25% { transform: translate(-1px,-2px) rotate(-2deg); }
30% { transform: translate(-1px,2px) rotate(-3deg); }
35% { transform: translate(2px,1px) rotate(6deg); }
40% { transform: translate(-2px,-3px) rotate(-9deg); }
45% { transform: translateY(-1px) rotate(-12deg); }
50% { transform: translate(1px,2px) rotate(10deg); }
55% { transform: translateY(-3px) rotate(8deg); }
60% { transform: translate(1px,-1px) rotate(8deg); }
65% { transform: translateY(-1px) rotate(-7deg); }
70% { transform: translate(-1px,-3px) rotate(6deg); }
75% { transform: translateY(-2px) rotate(4deg); }
80% { transform: translate(-2px,-1px) rotate(3deg); }
85% { transform: translate(1px,-3px) rotate(-10deg); }
90% { transform: translate(1px) rotate(3deg); }
95% { transform: translate(-2px) rotate(-3deg); }
to { transform: translate(2px,1px) rotate(2deg); }
}
.animation:hover {
animation: keywiggle 1s;
}
</style>

View File

@ -0,0 +1,30 @@
export function isFfVisibility(i, user):boolean {
let checkFlag:boolean;
switch (user.ffVisibility) {
case 'private':
checkFlag = false;
break;
case 'followers':
if (!user.isFollowing) {
checkFlag = false;
break;
}
// fallthrough
default: checkFlag = true;
}
if (!i) {
if (checkFlag) {
return true;
}
return false;
}
//自分自身の場合は一律true
if (i.id === user.id) {
return true;
}
return checkFlag;
}