forked from mirror/misskey
enhance: show recipients of notes with specified visibility (#8949)
* enhance: reusable visibility component * rename renote tooltip component The tooltip that is used for renotes can be used in other cases as well. * add tooltip for specified recipients * add changelog entry * Update visibility.vue Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
This commit is contained in:
parent
e560601815
commit
a1b8587ab2
@ -33,6 +33,7 @@ You should also include the user name that made the change.
|
|||||||
- Client: Word mute also checks content warnings @Johann150
|
- Client: Word mute also checks content warnings @Johann150
|
||||||
- Client: メニューからページをリロードできるように @syuilo
|
- Client: メニューからページをリロードできるように @syuilo
|
||||||
- Client: Improve emoji picker performance @syuilo
|
- Client: Improve emoji picker performance @syuilo
|
||||||
|
- Client: For notes with specified visibility, show recipients when hovering over visibility symbol. @Johann150
|
||||||
- Client: Make widgets available again on a tablet @syuilo
|
- Client: Make widgets available again on a tablet @syuilo
|
||||||
- ユーザーにモデレーションメモを残せる機能 @syuilo
|
- ユーザーにモデレーションメモを残せる機能 @syuilo
|
||||||
- Make possible to delete an account by admin @syuilo
|
- Make possible to delete an account by admin @syuilo
|
||||||
|
@ -26,12 +26,7 @@
|
|||||||
<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
|
<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
|
||||||
<MkTime :time="note.createdAt"/>
|
<MkTime :time="note.createdAt"/>
|
||||||
</button>
|
</button>
|
||||||
<span v-if="note.visibility !== 'public'" class="visibility">
|
<MkVisibility :note="note"/>
|
||||||
<i v-if="note.visibility === 'home'" class="fas fa-home"></i>
|
|
||||||
<i v-else-if="note.visibility === 'followers'" class="fas fa-unlock"></i>
|
|
||||||
<i v-else-if="note.visibility === 'specified'" class="fas fa-envelope"></i>
|
|
||||||
</span>
|
|
||||||
<span v-if="note.localOnly" class="localOnly"><i class="fas fa-biohazard"></i></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<article class="article" @contextmenu.stop="onContextmenu">
|
<article class="article" @contextmenu.stop="onContextmenu">
|
||||||
@ -43,12 +38,9 @@
|
|||||||
<MkUserName :user="appearNote.user"/>
|
<MkUserName :user="appearNote.user"/>
|
||||||
</MkA>
|
</MkA>
|
||||||
<span v-if="appearNote.user.isBot" class="is-bot">bot</span>
|
<span v-if="appearNote.user.isBot" class="is-bot">bot</span>
|
||||||
<span v-if="appearNote.visibility !== 'public'" class="visibility">
|
<div class="info">
|
||||||
<i v-if="appearNote.visibility === 'home'" class="fas fa-home"></i>
|
<MkVisibility :note="appearNote"/>
|
||||||
<i v-else-if="appearNote.visibility === 'followers'" class="fas fa-unlock"></i>
|
</div>
|
||||||
<i v-else-if="appearNote.visibility === 'specified'" class="fas fa-envelope"></i>
|
|
||||||
</span>
|
|
||||||
<span v-if="appearNote.localOnly" class="localOnly"><i class="fas fa-biohazard"></i></span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="username"><MkAcct :user="appearNote.user"/></div>
|
<div class="username"><MkAcct :user="appearNote.user"/></div>
|
||||||
<MkInstanceTicker v-if="showTicker" class="ticker" :instance="appearNote.user.instance"/>
|
<MkInstanceTicker v-if="showTicker" class="ticker" :instance="appearNote.user.instance"/>
|
||||||
@ -134,6 +126,7 @@ import XPoll from './poll.vue';
|
|||||||
import XRenoteButton from './renote-button.vue';
|
import XRenoteButton from './renote-button.vue';
|
||||||
import MkUrlPreview from '@/components/url-preview.vue';
|
import MkUrlPreview from '@/components/url-preview.vue';
|
||||||
import MkInstanceTicker from '@/components/instance-ticker.vue';
|
import MkInstanceTicker from '@/components/instance-ticker.vue';
|
||||||
|
import MkVisibility from '@/components/visibility.vue';
|
||||||
import { pleaseLogin } from '@/scripts/please-login';
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
import { checkWordMute } from '@/scripts/check-word-mute';
|
import { checkWordMute } from '@/scripts/check-word-mute';
|
||||||
import { userPage } from '@/filters/user';
|
import { userPage } from '@/filters/user';
|
||||||
@ -388,14 +381,6 @@ if (appearNote.replyId) {
|
|||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .visibility {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .localOnly {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,6 +426,10 @@ if (appearNote.replyId) {
|
|||||||
border: solid 0.5px var(--divider);
|
border: solid 0.5px var(--divider);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
> .info {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,7 @@
|
|||||||
<MkA class="created-at" :to="notePage(note)">
|
<MkA class="created-at" :to="notePage(note)">
|
||||||
<MkTime :time="note.createdAt"/>
|
<MkTime :time="note.createdAt"/>
|
||||||
</MkA>
|
</MkA>
|
||||||
<span v-if="note.visibility !== 'public'" class="visibility">
|
<MkVisibility :note="note"/>
|
||||||
<i v-if="note.visibility === 'home'" class="fas fa-home"></i>
|
|
||||||
<i v-else-if="note.visibility === 'followers'" class="fas fa-unlock"></i>
|
|
||||||
<i v-else-if="note.visibility === 'specified'" class="fas fa-envelope"></i>
|
|
||||||
</span>
|
|
||||||
<span v-if="note.localOnly" class="localOnly"><i class="fas fa-biohazard"></i></span>
|
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
@ -22,6 +17,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { } from 'vue';
|
import { } from 'vue';
|
||||||
import * as misskey from 'misskey-js';
|
import * as misskey from 'misskey-js';
|
||||||
|
import MkVisibility from '@/components/visibility.vue';
|
||||||
import { notePage } from '@/filters/note';
|
import { notePage } from '@/filters/note';
|
||||||
import { userPage } from '@/filters/user';
|
import { userPage } from '@/filters/user';
|
||||||
|
|
||||||
@ -74,14 +70,6 @@ defineProps<{
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
|
|
||||||
> .visibility {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .localOnly {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -28,12 +28,7 @@
|
|||||||
<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
|
<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
|
||||||
<MkTime :time="note.createdAt"/>
|
<MkTime :time="note.createdAt"/>
|
||||||
</button>
|
</button>
|
||||||
<span v-if="note.visibility !== 'public'" class="visibility">
|
<MkVisibility :note="note"/>
|
||||||
<i v-if="note.visibility === 'home'" class="fas fa-home"></i>
|
|
||||||
<i v-else-if="note.visibility === 'followers'" class="fas fa-unlock"></i>
|
|
||||||
<i v-else-if="note.visibility === 'specified'" class="fas fa-envelope"></i>
|
|
||||||
</span>
|
|
||||||
<span v-if="note.localOnly" class="localOnly"><i class="fas fa-biohazard"></i></span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<article class="article" @contextmenu.stop="onContextmenu">
|
<article class="article" @contextmenu.stop="onContextmenu">
|
||||||
@ -118,6 +113,7 @@ import XPoll from './poll.vue';
|
|||||||
import XRenoteButton from './renote-button.vue';
|
import XRenoteButton from './renote-button.vue';
|
||||||
import MkUrlPreview from '@/components/url-preview.vue';
|
import MkUrlPreview from '@/components/url-preview.vue';
|
||||||
import MkInstanceTicker from '@/components/instance-ticker.vue';
|
import MkInstanceTicker from '@/components/instance-ticker.vue';
|
||||||
|
import MkVisibility from '@/components/visibility.vue';
|
||||||
import { pleaseLogin } from '@/scripts/please-login';
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
import { focusPrev, focusNext } from '@/scripts/focus';
|
import { focusPrev, focusNext } from '@/scripts/focus';
|
||||||
import { checkWordMute } from '@/scripts/check-word-mute';
|
import { checkWordMute } from '@/scripts/check-word-mute';
|
||||||
@ -406,14 +402,6 @@ function readPromo() {
|
|||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .visibility {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .localOnly {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, ref } from 'vue';
|
import { computed, defineComponent, ref } from 'vue';
|
||||||
import XDetails from '@/components/renote.details.vue';
|
import XDetails from '@/components/users-tooltip.vue';
|
||||||
import { pleaseLogin } from '@/scripts/please-login';
|
import { pleaseLogin } from '@/scripts/please-login';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { $i } from '@/account';
|
import { $i } from '@/account';
|
||||||
|
47
packages/client/src/components/visibility.vue
Normal file
47
packages/client/src/components/visibility.vue
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<template>
|
||||||
|
<span v-if="note.visibility !== 'public'" :class="$style.visibility">
|
||||||
|
<i v-if="note.visibility === 'home'" class="fas fa-home"></i>
|
||||||
|
<i v-else-if="note.visibility === 'followers'" class="fas fa-unlock"></i>
|
||||||
|
<i v-else-if="note.visibility === 'specified'" ref="specified" class="fas fa-envelope"></i>
|
||||||
|
</span>
|
||||||
|
<span v-if="note.localOnly" :class="$style.localOnly"><i class="fas fa-biohazard"></i></span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import XDetails from '@/components/users-tooltip.vue';
|
||||||
|
import * as os from '@/os';
|
||||||
|
import { useTooltip } from '@/scripts/use-tooltip';
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
note: {
|
||||||
|
visibility: string;
|
||||||
|
localOnly?: boolean;
|
||||||
|
visibleUserIds?: string[];
|
||||||
|
},
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const specified = $ref<HTMLElement>();
|
||||||
|
|
||||||
|
if (props.note.visibility === 'specified') {
|
||||||
|
useTooltip($$(specified), async (showing) => {
|
||||||
|
const users = await os.api('users/show', {
|
||||||
|
userIds: props.note.visibleUserIds,
|
||||||
|
limit: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
os.popup(XDetails, {
|
||||||
|
showing,
|
||||||
|
users,
|
||||||
|
count: props.note.visibleUserIds.length,
|
||||||
|
targetElement: specified,
|
||||||
|
}, {}, 'closed');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
||||||
|
.visibility, .localOnly {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user