Merge branch 'develop' into merge/2024-02-03
# Conflicts: # locales/index.d.ts # packages/backend/src/core/entities/UserEntityService.ts # packages/frontend/src/_dev_boot_.ts # packages/misskey-js/src/autogen/types.ts # sharkey-locales/en-US.yml
This commit is contained in:
commit
f36029f795
24 changed files with 512 additions and 35 deletions
|
|
@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<MkRemoteCaution v-if="user.host != null" :href="user.url ?? user.uri!" class="warn"/>
|
||||
|
||||
<div :key="user.id" class="main _panel">
|
||||
<div class="banner-container" :style="style">
|
||||
<div class="banner-container" :class="{ [$style.bannerContainerTall]: useTallBanner }" :style="style">
|
||||
<div ref="bannerEl" class="banner" :style="style"></div>
|
||||
<div class="fade"></div>
|
||||
<div class="title">
|
||||
|
|
@ -39,12 +39,15 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||
<li v-if="user.isBlocking">{{ i18n.ts.blocked }}</li>
|
||||
<li v-if="user.isBlocked && $i.isModerator">{{ i18n.ts.blockingYou }}</li>
|
||||
</ul>
|
||||
<div class="actions">
|
||||
<button class="menu _button" @click="menu"><i class="ti ti-dots"></i></button>
|
||||
<MkFollowButton v-if="$i?.id != user.id" v-model:user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/>
|
||||
<div :class="$style.actions" class="actions">
|
||||
<button :class="$style.actionsMenu" class="menu _button" @click="menu"><i class="ti ti-dots"></i></button>
|
||||
<MkFollowButton v-if="$i?.id != user.id" v-model:user="user" :class="$style.actionsFollow" :disabled="disableFollowControls" :inline="true" :transparent="false" :full="true" class="koudoku" @update:wait="onFollowButtonDisabledChanged"/>
|
||||
<div v-if="hasFollowRequest" :class="$style.actionsBanner">{{ i18n.ts.receiveFollowRequest }}</div>
|
||||
<MkButton v-if="hasFollowRequest" :class="$style.actionsAccept" :disabled="disableFollowControls" :inline="true" :transparent="false" :full="true" rounded primary @click="acceptFollowRequest"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
|
||||
<MkButton v-if="hasFollowRequest" :class="$style.actionsReject" :disabled="disableFollowControls" :inline="true" :transparent="false" :full="true" rounded danger @click="rejectFollowRequest"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
|
||||
</div>
|
||||
</div>
|
||||
<MkAvatar class="avatar" :user="user" indicator/>
|
||||
<MkAvatar class="avatar" :class="{ [$style.avatarTall]: useTallBanner }" :user="user" indicator/>
|
||||
<div class="title">
|
||||
<MkUserName :user="user" :nowrap="false" class="name"/>
|
||||
<div class="bottom">
|
||||
|
|
@ -220,8 +223,8 @@ import MkSparkle from '@/components/MkSparkle.vue';
|
|||
|
||||
const MkNote = defineAsyncComponent(() =>
|
||||
defaultStore.state.noteDesign === 'sharkey'
|
||||
? import('@/components/SkNote.vue')
|
||||
: import('@/components/MkNote.vue'),
|
||||
? import('@/components/SkNote.vue')
|
||||
: import('@/components/MkNote.vue'),
|
||||
);
|
||||
|
||||
function calcAge(birthdate: string): number {
|
||||
|
|
@ -387,6 +390,42 @@ async function updateMemo() {
|
|||
isEditingMemo.value = false;
|
||||
}
|
||||
|
||||
// Set true to disable the follow / follow request controls
|
||||
const disableFollowControls = ref(false);
|
||||
const hasFollowRequest = computed(() => user.value.hasPendingFollowRequestToYou);
|
||||
const useTallBanner = computed(() => hasFollowRequest.value && narrow.value);
|
||||
|
||||
async function onFollowButtonDisabledChanged(disabled: boolean) {
|
||||
try {
|
||||
// Refresh the UI after MkFollowButton changes the follow relation
|
||||
if (!disabled) {
|
||||
user.value = await os.apiWithDialog('users/show', { userId: user.value.id });
|
||||
}
|
||||
} finally {
|
||||
disableFollowControls.value = disabled;
|
||||
}
|
||||
}
|
||||
|
||||
async function acceptFollowRequest() {
|
||||
try {
|
||||
disableFollowControls.value = true;
|
||||
await os.apiWithDialog('following/requests/accept', { userId: user.value.id });
|
||||
user.value = await os.apiWithDialog('users/show', { userId: user.value.id });
|
||||
} finally {
|
||||
disableFollowControls.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function rejectFollowRequest() {
|
||||
try {
|
||||
disableFollowControls.value = true;
|
||||
await os.apiWithDialog('following/requests/reject', { userId: user.value.id });
|
||||
user.value = await os.apiWithDialog('users/show', { userId: user.value.id });
|
||||
} finally {
|
||||
disableFollowControls.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
watch([props.user], () => {
|
||||
memoDraft.value = props.user.memo;
|
||||
});
|
||||
|
|
@ -863,4 +902,48 @@ onUnmounted(() => {
|
|||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: grid;
|
||||
grid-template-rows: min-content min-content min-content;
|
||||
grid-template-columns: min-content auto 1fr;
|
||||
grid-template-areas:
|
||||
"menu follow follow"
|
||||
"banner banner banner"
|
||||
"accept accept reject";
|
||||
}
|
||||
|
||||
.actionsMenu {
|
||||
grid-area: menu;
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.actionsFollow {
|
||||
grid-area: follow;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.actionsBanner {
|
||||
grid-area: banner;
|
||||
justify-self: center;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.actionsAccept {
|
||||
grid-area: accept;
|
||||
}
|
||||
|
||||
.actionsReject {
|
||||
grid-area: reject;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.bannerContainerTall {
|
||||
height: 200px !important;
|
||||
}
|
||||
|
||||
.avatarTall {
|
||||
top: 150px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue