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:
commit
2ce329a1a9
@ -15,6 +15,7 @@
|
||||
## 13.13.1 (unreleased)
|
||||
|
||||
### Client
|
||||
- フォロー/フォロワーを非公開としている場合、表示は「0」ではなく鍵アイコンを表示するように
|
||||
- Fix: タブがアクティブな間はstreamが切断されないように
|
||||
|
||||
### General
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
30
packages/frontend/src/scripts/is-ff-visibility.ts
Normal file
30
packages/frontend/src/scripts/is-ff-visibility.ts
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user