diff options
Diffstat (limited to 'packages/frontend/src/pages')
| -rw-r--r-- | packages/frontend/src/pages/admin/roles.editor.vue | 21 | ||||
| -rw-r--r-- | packages/frontend/src/pages/admin/roles.vue | 14 | ||||
| -rw-r--r-- | packages/frontend/src/pages/chat/XMessage.vue | 10 | ||||
| -rw-r--r-- | packages/frontend/src/pages/chat/home.home.vue | 4 | ||||
| -rw-r--r-- | packages/frontend/src/pages/chat/room.vue | 84 | ||||
| -rw-r--r-- | packages/frontend/src/pages/settings/preferences.vue | 75 | ||||
| -rw-r--r-- | packages/frontend/src/pages/settings/privacy.vue | 33 |
7 files changed, 131 insertions, 110 deletions
diff --git a/packages/frontend/src/pages/admin/roles.editor.vue b/packages/frontend/src/pages/admin/roles.editor.vue index 73119940c1..930a63f5a9 100644 --- a/packages/frontend/src/pages/admin/roles.editor.vue +++ b/packages/frontend/src/pages/admin/roles.editor.vue @@ -165,21 +165,24 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </MkFolder> - <MkFolder v-if="matchQuery([i18n.ts._role._options.canChat, 'canChat'])"> - <template #label>{{ i18n.ts._role._options.canChat }}</template> + <MkFolder v-if="matchQuery([i18n.ts._role._options.chatAvailability, 'chatAvailability'])"> + <template #label>{{ i18n.ts._role._options.chatAvailability }}</template> <template #suffix> - <span v-if="role.policies.canChat.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span> - <span v-else>{{ role.policies.canChat.value ? i18n.ts.yes : i18n.ts.no }}</span> - <span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.canChat)"></i></span> + <span v-if="role.policies.chatAvailability.useDefault" :class="$style.useDefaultLabel">{{ i18n.ts._role.useBaseValue }}</span> + <span v-else>{{ role.policies.chatAvailability.value === 'available' ? i18n.ts.yes : role.policies.chatAvailability.value === 'readonly' ? i18n.ts.readonly : i18n.ts.no }}</span> + <span :class="$style.priorityIndicator"><i :class="getPriorityIcon(role.policies.chatAvailability)"></i></span> </template> <div class="_gaps"> - <MkSwitch v-model="role.policies.canChat.useDefault" :readonly="readonly"> + <MkSwitch v-model="role.policies.chatAvailability.useDefault" :readonly="readonly"> <template #label>{{ i18n.ts._role.useBaseValue }}</template> </MkSwitch> - <MkSwitch v-model="role.policies.canChat.value" :disabled="role.policies.canChat.useDefault" :readonly="readonly"> + <MkSelect v-model="role.policies.chatAvailability.value" :disabled="role.policies.chatAvailability.useDefault" :readonly="readonly"> <template #label>{{ i18n.ts.enable }}</template> - </MkSwitch> - <MkRange v-model="role.policies.canChat.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''"> + <option value="available">{{ i18n.ts.enabled }}</option> + <option value="readonly">{{ i18n.ts.readonly }}</option> + <option value="unavailable">{{ i18n.ts.disabled }}</option> + </MkSelect> + <MkRange v-model="role.policies.chatAvailability.priority" :min="0" :max="2" :step="1" easing :textConverter="(v) => v === 0 ? i18n.ts._role._priority.low : v === 1 ? i18n.ts._role._priority.middle : v === 2 ? i18n.ts._role._priority.high : ''"> <template #label>{{ i18n.ts._role.priority }}</template> </MkRange> </div> diff --git a/packages/frontend/src/pages/admin/roles.vue b/packages/frontend/src/pages/admin/roles.vue index df4efd1271..7c950957cf 100644 --- a/packages/frontend/src/pages/admin/roles.vue +++ b/packages/frontend/src/pages/admin/roles.vue @@ -51,12 +51,15 @@ SPDX-License-Identifier: AGPL-3.0-only </MkSwitch> </MkFolder> - <MkFolder v-if="matchQuery([i18n.ts._role._options.canChat, 'canChat'])"> - <template #label>{{ i18n.ts._role._options.canChat }}</template> - <template #suffix>{{ policies.canChat ? i18n.ts.yes : i18n.ts.no }}</template> - <MkSwitch v-model="policies.canChat"> + <MkFolder v-if="matchQuery([i18n.ts._role._options.chatAvailability, 'chatAvailability'])"> + <template #label>{{ i18n.ts._role._options.chatAvailability }}</template> + <template #suffix>{{ policies.chatAvailability === 'available' ? i18n.ts.yes : policies.chatAvailability === 'readonly' ? i18n.ts.readonly : i18n.ts.no }}</template> + <MkSelect v-model="policies.chatAvailability"> <template #label>{{ i18n.ts.enable }}</template> - </MkSwitch> + <option value="available">{{ i18n.ts.enabled }}</option> + <option value="readonly">{{ i18n.ts.readonly }}</option> + <option value="unavailable">{{ i18n.ts.disabled }}</option> + </MkSelect> </MkFolder> <MkFolder v-if="matchQuery([i18n.ts._role._options.mentionMax, 'mentionLimit'])"> @@ -295,6 +298,7 @@ import MkInput from '@/components/MkInput.vue'; import MkFolder from '@/components/MkFolder.vue'; import MkSwitch from '@/components/MkSwitch.vue'; import MkButton from '@/components/MkButton.vue'; +import MkSelect from '@/components/MkSelect.vue'; import MkRange from '@/components/MkRange.vue'; import MkRolePreview from '@/components/MkRolePreview.vue'; import * as os from '@/os.js'; diff --git a/packages/frontend/src/pages/chat/XMessage.vue b/packages/frontend/src/pages/chat/XMessage.vue index eb8b0d79ee..def6ec7d14 100644 --- a/packages/frontend/src/pages/chat/XMessage.vue +++ b/packages/frontend/src/pages/chat/XMessage.vue @@ -85,7 +85,7 @@ const isMe = computed(() => props.message.fromUserId === $i.id); const urls = computed(() => props.message.text ? extractUrlFromMfm(mfm.parse(props.message.text)) : []); provide(DI.mfmEmojiReactCallback, (reaction) => { - if (!$i.policies.canChat) return; + if ($i.policies.chatAvailability !== 'available') return; sound.playMisskeySfx('reaction'); misskeyApi('chat/messages/react', { @@ -95,7 +95,7 @@ provide(DI.mfmEmojiReactCallback, (reaction) => { }); function react(ev: MouseEvent) { - if (!$i.policies.canChat) return; + if ($i.policies.chatAvailability !== 'available') return; const targetEl = getHTMLElementOrNull(ev.currentTarget ?? ev.target); if (!targetEl) return; @@ -110,7 +110,7 @@ function react(ev: MouseEvent) { } function onReactionClick(record: Misskey.entities.ChatMessage['reactions'][0]) { - if (!$i.policies.canChat) return; + if ($i.policies.chatAvailability !== 'available') return; if (record.user.id === $i.id) { misskeyApi('chat/messages/unreact', { @@ -138,7 +138,7 @@ function onContextmenu(ev: MouseEvent) { function showMenu(ev: MouseEvent, contextmenu = false) { const menu: MenuItem[] = []; - if (!isMe.value && $i.policies.canChat) { + if (!isMe.value && $i.policies.chatAvailability === 'available') { menu.push({ text: i18n.ts.reaction, icon: 'ti ti-mood-plus', @@ -164,7 +164,7 @@ function showMenu(ev: MouseEvent, contextmenu = false) { type: 'divider', }); - if (isMe.value && $i.policies.canChat) { + if (isMe.value && $i.policies.chatAvailability === 'available') { menu.push({ text: i18n.ts.delete, icon: 'ti ti-trash', diff --git a/packages/frontend/src/pages/chat/home.home.vue b/packages/frontend/src/pages/chat/home.home.vue index 17f0e0fbcd..a8ed891de0 100644 --- a/packages/frontend/src/pages/chat/home.home.vue +++ b/packages/frontend/src/pages/chat/home.home.vue @@ -5,9 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div class="_gaps"> - <MkButton v-if="$i.policies.canChat" primary gradate rounded :class="$style.start" @click="start"><i class="ti ti-plus"></i> {{ i18n.ts.startChat }}</MkButton> + <MkButton v-if="$i.policies.chatAvailability === 'available'" primary gradate rounded :class="$style.start" @click="start"><i class="ti ti-plus"></i> {{ i18n.ts.startChat }}</MkButton> - <MkInfo v-else>{{ i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo> + <MkInfo v-else>{{ $i.policies.chatAvailability === 'readonly' ? i18n.ts._chat.chatIsReadOnlyForThisAccountOrServer : i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo> <MkAd :preferForms="['horizontal', 'horizontal-big']"/> diff --git a/packages/frontend/src/pages/chat/room.vue b/packages/frontend/src/pages/chat/room.vue index 9942dbeee9..8b351c1ec8 100644 --- a/packages/frontend/src/pages/chat/room.vue +++ b/packages/frontend/src/pages/chat/room.vue @@ -6,54 +6,56 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <PageWithHeader v-model:tab="tab" :reversed="tab === 'chat'" :tabs="headerTabs" :actions="headerActions"> <MkSpacer v-if="tab === 'chat'" :contentMax="700"> - <div v-if="initializing"> - <MkLoading/> - </div> + <div class="_gaps"> + <div v-if="initializing"> + <MkLoading/> + </div> - <div v-else-if="messages.length === 0"> - <div class="_gaps" style="text-align: center;"> - <div>{{ i18n.ts._chat.noMessagesYet }}</div> - <template v-if="user"> - <div v-if="user.chatScope === 'followers'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowers }}</div> - <div v-else-if="user.chatScope === 'following'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowing }}</div> - <div v-else-if="user.chatScope === 'mutual'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromMutualFollowing }}</div> - <div v-else-if="user.chatScope === 'none'">{{ i18n.ts._chat.thisUserNotAllowedChatAnyone }}</div> - </template> - <template v-else-if="room"> - <div>{{ i18n.ts._chat.inviteUserToChat }}</div> - </template> + <div v-else-if="messages.length === 0"> + <div class="_gaps" style="text-align: center;"> + <div>{{ i18n.ts._chat.noMessagesYet }}</div> + <template v-if="user"> + <div v-if="user.chatScope === 'followers'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowers }}</div> + <div v-else-if="user.chatScope === 'following'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowing }}</div> + <div v-else-if="user.chatScope === 'mutual'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromMutualFollowing }}</div> + <div v-else-if="user.chatScope === 'none'">{{ i18n.ts._chat.thisUserNotAllowedChatAnyone }}</div> + </template> + <template v-else-if="room"> + <div>{{ i18n.ts._chat.inviteUserToChat }}</div> + </template> + </div> </div> - </div> - <div v-else ref="timelineEl" class="_gaps"> - <div v-if="canFetchMore"> - <MkButton :class="$style.more" :wait="moreFetching" primary rounded @click="fetchMore">{{ i18n.ts.loadMore }}</MkButton> + <div v-else ref="timelineEl" class="_gaps"> + <div v-if="canFetchMore"> + <MkButton :class="$style.more" :wait="moreFetching" primary rounded @click="fetchMore">{{ i18n.ts.loadMore }}</MkButton> + </div> + + <TransitionGroup + :enterActiveClass="prefer.s.animation ? $style.transition_x_enterActive : ''" + :leaveActiveClass="prefer.s.animation ? $style.transition_x_leaveActive : ''" + :enterFromClass="prefer.s.animation ? $style.transition_x_enterFrom : ''" + :leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''" + :moveClass="prefer.s.animation ? $style.transition_x_move : ''" + tag="div" class="_gaps" + > + <template v-for="item in timeline.toReversed()" :key="item.id"> + <XMessage v-if="item.type === 'item'" :message="item.data"/> + <div v-else-if="item.type === 'date'" :class="$style.dateDivider"> + <span><i class="ti ti-chevron-up"></i> {{ item.nextText }}</span> + <span style="height: 1em; width: 1px; background: var(--MI_THEME-divider);"></span> + <span>{{ item.prevText }} <i class="ti ti-chevron-down"></i></span> + </div> + </template> + </TransitionGroup> </div> - <TransitionGroup - :enterActiveClass="prefer.s.animation ? $style.transition_x_enterActive : ''" - :leaveActiveClass="prefer.s.animation ? $style.transition_x_leaveActive : ''" - :enterFromClass="prefer.s.animation ? $style.transition_x_enterFrom : ''" - :leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''" - :moveClass="prefer.s.animation ? $style.transition_x_move : ''" - tag="div" class="_gaps" - > - <template v-for="item in timeline.toReversed()" :key="item.id"> - <XMessage v-if="item.type === 'item'" :message="item.data"/> - <div v-else-if="item.type === 'date'" :class="$style.dateDivider"> - <span><i class="ti ti-chevron-up"></i> {{ item.nextText }}</span> - <span style="height: 1em; width: 1px; background: var(--MI_THEME-divider);"></span> - <span>{{ item.prevText }} <i class="ti ti-chevron-down"></i></span> - </div> - </template> - </TransitionGroup> - </div> + <div v-if="user && (!user.canChat || user.host !== null)"> + <MkInfo warn>{{ i18n.ts._chat.chatNotAvailableInOtherAccount }}</MkInfo> + </div> - <div v-if="user && (!user.canChat || user.host !== null)"> - <MkInfo warn>{{ i18n.ts._chat.chatNotAvailableInOtherAccount }}</MkInfo> + <MkInfo v-if="$i.policies.chatAvailability !== 'available'" warn>{{ $i.policies.chatAvailability === 'readonly' ? i18n.ts._chat.chatIsReadOnlyForThisAccountOrServer : i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo> </div> - - <MkInfo v-if="!$i.policies.canChat" warn>{{ i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo> </MkSpacer> <MkSpacer v-else-if="tab === 'search'" :contentMax="700"> diff --git a/packages/frontend/src/pages/settings/preferences.vue b/packages/frontend/src/pages/settings/preferences.vue index 647fed10e3..42a7b486ed 100644 --- a/packages/frontend/src/pages/settings/preferences.vue +++ b/packages/frontend/src/pages/settings/preferences.vue @@ -379,44 +379,46 @@ SPDX-License-Identifier: AGPL-3.0-only </MkFolder> </SearchMarker> - <SearchMarker :keywords="['chat', 'messaging']"> - <MkFolder> - <template #label><SearchLabel>{{ i18n.ts.chat }}</SearchLabel></template> - <template #icon><SearchIcon><i class="ti ti-messages"></i></SearchIcon></template> + <template v-if="$i.policies.chatAvailability !== 'unavailable'"> + <SearchMarker :keywords="['chat', 'messaging']"> + <MkFolder> + <template #label><SearchLabel>{{ i18n.ts.chat }}</SearchLabel></template> + <template #icon><SearchIcon><i class="ti ti-messages"></i></SearchIcon></template> - <div class="_gaps_s"> - <SearchMarker :keywords="['show', 'sender', 'name']"> - <MkPreferenceContainer k="chat.showSenderName"> - <MkSwitch v-model="chatShowSenderName"> - <template #label><SearchLabel>{{ i18n.ts._settings._chat.showSenderName }}</SearchLabel></template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> + <div class="_gaps_s"> + <SearchMarker :keywords="['show', 'sender', 'name']"> + <MkPreferenceContainer k="chat.showSenderName"> + <MkSwitch v-model="chatShowSenderName"> + <template #label><SearchLabel>{{ i18n.ts._settings._chat.showSenderName }}</SearchLabel></template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> - <SearchMarker :keywords="['send', 'enter', 'newline']"> - <MkPreferenceContainer k="chat.sendOnEnter"> - <MkSwitch v-model="chatSendOnEnter"> - <template #label><SearchLabel>{{ i18n.ts._settings._chat.sendOnEnter }}</SearchLabel></template> - <template #caption> - <div class="_gaps_s"> - <div> - <b>{{ i18n.ts._settings.ifOn }}:</b> - <div>{{ i18n.ts._chat.send }}: Enter</div> - <div>{{ i18n.ts._chat.newline }}: Shift + Enter</div> + <SearchMarker :keywords="['send', 'enter', 'newline']"> + <MkPreferenceContainer k="chat.sendOnEnter"> + <MkSwitch v-model="chatSendOnEnter"> + <template #label><SearchLabel>{{ i18n.ts._settings._chat.sendOnEnter }}</SearchLabel></template> + <template #caption> + <div class="_gaps_s"> + <div> + <b>{{ i18n.ts._settings.ifOn }}:</b> + <div>{{ i18n.ts._chat.send }}: Enter</div> + <div>{{ i18n.ts._chat.newline }}: Shift + Enter</div> + </div> + <div> + <b>{{ i18n.ts._settings.ifOff }}:</b> + <div>{{ i18n.ts._chat.send }}: Ctrl + Enter</div> + <div>{{ i18n.ts._chat.newline }}: Enter</div> + </div> </div> - <div> - <b>{{ i18n.ts._settings.ifOff }}:</b> - <div>{{ i18n.ts._chat.send }}: Ctrl + Enter</div> - <div>{{ i18n.ts._chat.newline }}: Enter</div> - </div> - </div> - </template> - </MkSwitch> - </MkPreferenceContainer> - </SearchMarker> - </div> - </MkFolder> - </SearchMarker> + </template> + </MkSwitch> + </MkPreferenceContainer> + </SearchMarker> + </div> + </MkFolder> + </SearchMarker> + </template> <SearchMarker :keywords="['accessibility']"> <MkFolder> @@ -732,6 +734,9 @@ import MkFeatureBanner from '@/components/MkFeatureBanner.vue'; import { globalEvents } from '@/events.js'; import { claimAchievement } from '@/utility/achievements.js'; import { instance } from '@/instance.js'; +import { ensureSignin } from '@/i.js'; + +const $i = ensureSignin(); const lang = ref(miLocalStorage.getItem('lang')); const dataSaver = ref(prefer.s.dataSaver); diff --git a/packages/frontend/src/pages/settings/privacy.vue b/packages/frontend/src/pages/settings/privacy.vue index 2f8a697d74..4e6425667e 100644 --- a/packages/frontend/src/pages/settings/privacy.vue +++ b/packages/frontend/src/pages/settings/privacy.vue @@ -78,19 +78,26 @@ SPDX-License-Identifier: AGPL-3.0-only </MkSwitch> </SearchMarker> - <FormSection> - <SearchMarker :keywords="['chat']"> - <MkSelect v-model="chatScope" @update:modelValue="save()"> - <template #label><SearchLabel>{{ i18n.ts._chat.chatAllowedUsers }}</SearchLabel></template> - <option value="everyone">{{ i18n.ts._chat._chatAllowedUsers.everyone }}</option> - <option value="followers">{{ i18n.ts._chat._chatAllowedUsers.followers }}</option> - <option value="following">{{ i18n.ts._chat._chatAllowedUsers.following }}</option> - <option value="mutual">{{ i18n.ts._chat._chatAllowedUsers.mutual }}</option> - <option value="none">{{ i18n.ts._chat._chatAllowedUsers.none }}</option> - <template #caption>{{ i18n.ts._chat.chatAllowedUsers_note }}</template> - </MkSelect> - </SearchMarker> - </FormSection> + <SearchMarker :keywords="['chat']"> + <FormSection> + <template #label><SearchLabel>{{ i18n.ts.chat }}</SearchLabel></template> + + <div class="_gaps_m"> + <MkInfo v-if="$i.policies.chatAvailability === 'unavailable'">{{ i18n.ts._chat.chatNotAvailableForThisAccountOrServer }}</MkInfo> + <SearchMarker :keywords="['chat']"> + <MkSelect v-model="chatScope" @update:modelValue="save()"> + <template #label><SearchLabel>{{ i18n.ts._chat.chatAllowedUsers }}</SearchLabel></template> + <option value="everyone">{{ i18n.ts._chat._chatAllowedUsers.everyone }}</option> + <option value="followers">{{ i18n.ts._chat._chatAllowedUsers.followers }}</option> + <option value="following">{{ i18n.ts._chat._chatAllowedUsers.following }}</option> + <option value="mutual">{{ i18n.ts._chat._chatAllowedUsers.mutual }}</option> + <option value="none">{{ i18n.ts._chat._chatAllowedUsers.none }}</option> + <template #caption>{{ i18n.ts._chat.chatAllowedUsers_note }}</template> + </MkSelect> + </SearchMarker> + </div> + </FormSection> + </SearchMarker> <SearchMarker :keywords="['lockdown']"> <FormSection> |