Compare commits
2 Commits
e91c1040e2
...
4ea5d7c106
Author | SHA1 | Date |
---|---|---|
Natty | 4ea5d7c106 | |
Natty | 1b87a57b8c |
|
@ -3,6 +3,7 @@
|
|||
"private": true,
|
||||
"scripts": {
|
||||
"watch": "pnpm vite build --watch --mode development",
|
||||
"watchRebuild": "pnpm vite build --watch",
|
||||
"build": "pnpm vite build",
|
||||
"format": "pnpm prettier --write '**/*.vue'"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<template v-if="waitIncoming">
|
||||
<i class="ph-circle-notch ph-bold ph-lg fa-pulse ph-fw ph-lg"></i>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button
|
||||
class="_textButton"
|
||||
:disabled="waitIncoming"
|
||||
@click.stop="accept(user)"
|
||||
>
|
||||
<i class="ph-check ph-bold ph-lg"></i>
|
||||
<span class="follow-approve-label">
|
||||
{{ i18n.ts.accept }}
|
||||
</span>
|
||||
</button>
|
||||
|
|
||||
<button
|
||||
class="_textButton"
|
||||
:disabled="waitIncoming"
|
||||
@click.stop="reject(user)"
|
||||
>
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
<span class="follow-approve-label">
|
||||
{{ i18n.ts.reject }}
|
||||
</span>
|
||||
</button>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onBeforeUnmount, onMounted } from "vue";
|
||||
import type * as Misskey from "calckey-js";
|
||||
import * as os from "@/os";
|
||||
import { i18n } from "@/i18n";
|
||||
import { useRouter } from "@/router";
|
||||
import { stream } from "@/stream";
|
||||
import { globalEvents } from "@/events";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const emit = defineEmits(["refresh"]);
|
||||
const props = defineProps<{
|
||||
user: Misskey.entities.User;
|
||||
}>();
|
||||
|
||||
let state = $ref(i18n.ts.processing);
|
||||
const connection = stream.useChannel("main");
|
||||
|
||||
let waitIncoming = $ref(false);
|
||||
|
||||
function accept(user: Misskey.entities.User) {
|
||||
waitIncoming = true;
|
||||
os.api("following/requests/accept", { userId: user.id }).then(() => {
|
||||
globalEvents.emit("followeeProcessed", user);
|
||||
});
|
||||
}
|
||||
|
||||
function reject(user: Misskey.entities.User) {
|
||||
waitIncoming = true;
|
||||
os.api("following/requests/reject", { userId: user.id }).then(() => {
|
||||
globalEvents.emit("followeeProcessed", user);
|
||||
});
|
||||
}
|
||||
|
||||
function onFolloweeChange(user: Misskey.entities.User) {
|
||||
if (user.id === props.user.id) {
|
||||
emit("refresh");
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
globalEvents.on("followeeProcessed", () => onFolloweeChange(props.user));
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
globalEvents.off("followeeProcessed", () => onFolloweeChange(props.user));
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.follow-approve-label {
|
||||
padding-left: 0.25em;
|
||||
}
|
||||
</style>
|
|
@ -7,47 +7,6 @@
|
|||
>
|
||||
<i class="ph-dots-three-outline ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<span
|
||||
class="follow-menu"
|
||||
:class="{
|
||||
large,
|
||||
full,
|
||||
}"
|
||||
v-if="
|
||||
$i != null && $i.id != user.id && user.hasPendingFollowRequestToYou
|
||||
"
|
||||
>
|
||||
<span v-if="full">
|
||||
{{ i18n.ts.followRequestYou }}
|
||||
</span>
|
||||
<span v-else>
|
||||
<i
|
||||
class="ph-hand-waving ph-bold ph-lg"
|
||||
:aria-label="i18n.ts.followRequestYou"
|
||||
></i>
|
||||
</span>
|
||||
<template v-if="waitIncoming">
|
||||
<i class="ph-circle-notch ph-bold ph-lg fa-pulse"></i>
|
||||
</template>
|
||||
<template v-else>
|
||||
<button
|
||||
class="_button follow-incoming"
|
||||
:disabled="waitIncoming"
|
||||
@click.stop="accept(user)"
|
||||
v-tooltip="i18n.ts.accept"
|
||||
>
|
||||
<i class="ph-check ph-bold ph-lg"></i>
|
||||
</button>
|
||||
<button
|
||||
class="_button follow-incoming"
|
||||
:disabled="waitIncoming"
|
||||
@click.stop="reject(user)"
|
||||
v-tooltip="i18n.ts.reject"
|
||||
>
|
||||
<i class="ph-x ph-bold ph-lg"></i>
|
||||
</button>
|
||||
</template>
|
||||
</span>
|
||||
<button
|
||||
v-if="$i != null && $i.id != user.id"
|
||||
class="kpoogebi _button follow-button"
|
||||
|
@ -136,23 +95,8 @@ let hasPendingFollowRequestFromYou = $ref(
|
|||
props.user.hasPendingFollowRequestFromYou
|
||||
);
|
||||
let wait = $ref(false);
|
||||
let waitIncoming = $ref(false);
|
||||
const connection = stream.useChannel("main");
|
||||
|
||||
function accept(user) {
|
||||
waitIncoming = true;
|
||||
os.api("following/requests/accept", { userId: user.id }).then(() => {
|
||||
emit("refresh");
|
||||
});
|
||||
}
|
||||
|
||||
function reject(user) {
|
||||
waitIncoming = true;
|
||||
os.api("following/requests/reject", { userId: user.id }).then(() => {
|
||||
emit("refresh");
|
||||
});
|
||||
}
|
||||
|
||||
if (props.user.isFollowing == null) {
|
||||
os.api("users/show", {
|
||||
userId: props.user.id,
|
||||
|
@ -242,55 +186,6 @@ onBeforeUnmount(() => {
|
|||
height: 2em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.follow-menu {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
color: var(--accent);
|
||||
border: solid 1px var(--accent);
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
height: 2em;
|
||||
border-radius: 100px;
|
||||
background: var(--bg);
|
||||
vertical-align: middle;
|
||||
|
||||
&.full {
|
||||
padding: 0.2em 0.7em;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&.large {
|
||||
font-size: 16px;
|
||||
height: 38px;
|
||||
padding: 0 12px 0 16px;
|
||||
}
|
||||
|
||||
&.follow-incoming {
|
||||
margin: 0 0.5em;
|
||||
|
||||
border-inline-start: solid 1px var(--accent);
|
||||
|
||||
&.active {
|
||||
color: var(--fgOnAccent);
|
||||
background: var(--accent);
|
||||
|
||||
&:hover {
|
||||
background: var(--accentLighten);
|
||||
border-color: var(--accentLighten);
|
||||
}
|
||||
|
||||
&:active {
|
||||
background: var(--accentDarken);
|
||||
border-color: var(--accentDarken);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.follow-button {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
|
|
|
@ -220,8 +220,9 @@
|
|||
:user="notification.user"
|
||||
:full="true"
|
||||
:hideMenu="true"
|
||||
/></div
|
||||
></span>
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
v-if="notification.type === 'followRequestAccepted'"
|
||||
class="text"
|
||||
|
@ -234,15 +235,12 @@
|
|||
style="opacity: 0.7"
|
||||
>{{ i18n.ts.receiveFollowRequest }}
|
||||
<div v-if="full && !followRequestDone">
|
||||
<button class="_textButton" @click="acceptFollowRequest()">
|
||||
{{ i18n.ts.accept }}
|
||||
</button>
|
||||
|
|
||||
<button class="_textButton" @click="rejectFollowRequest()">
|
||||
{{ i18n.ts.reject }}
|
||||
</button>
|
||||
</div></span
|
||||
>
|
||||
<MkFollowApproveButton
|
||||
:user="notification.user"
|
||||
@refresh="followRequestDone = true"
|
||||
/>
|
||||
</div>
|
||||
</span>
|
||||
<span
|
||||
v-if="notification.type === 'groupInvited'"
|
||||
class="text"
|
||||
|
@ -263,8 +261,8 @@
|
|||
>
|
||||
{{ i18n.ts.reject }}
|
||||
</button>
|
||||
</div></span
|
||||
>
|
||||
</div>
|
||||
</span>
|
||||
<span v-if="notification.type === 'app'" class="text">
|
||||
<Mfm :text="notification.body" :nowrap="!full" />
|
||||
</span>
|
||||
|
@ -273,7 +271,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, onUnmounted, watch } from "vue";
|
||||
import { onMounted, onUnmounted, ref, watch } from "vue";
|
||||
import * as misskey from "calckey-js";
|
||||
import XReactionIcon from "@/components/MkReactionIcon.vue";
|
||||
import MkFollowButton from "@/components/MkFollowButton.vue";
|
||||
|
@ -287,6 +285,7 @@ import { stream } from "@/stream";
|
|||
import { useTooltip } from "@/scripts/use-tooltip";
|
||||
import { defaultStore } from "@/store";
|
||||
import { instance } from "@/instance";
|
||||
import MkFollowApproveButton from "@/components/MkFollowApproveButton.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -300,6 +299,7 @@ const props = withDefaults(
|
|||
}
|
||||
);
|
||||
|
||||
const emit = defineEmits(["refresh"]);
|
||||
const elRef = ref<HTMLElement>(null);
|
||||
const reactionRef = ref(null);
|
||||
|
||||
|
@ -342,16 +342,6 @@ onUnmounted(() => {
|
|||
const followRequestDone = ref(false);
|
||||
const groupInviteDone = ref(false);
|
||||
|
||||
const acceptFollowRequest = () => {
|
||||
followRequestDone.value = true;
|
||||
os.api("following/requests/accept", { userId: props.notification.user.id });
|
||||
};
|
||||
|
||||
const rejectFollowRequest = () => {
|
||||
followRequestDone.value = true;
|
||||
os.api("following/requests/reject", { userId: props.notification.user.id });
|
||||
};
|
||||
|
||||
const acceptGroupInvitation = () => {
|
||||
groupInviteDone.value = true;
|
||||
os.apiWithDialog("users/groups/invitations/accept", {
|
||||
|
|
|
@ -80,30 +80,44 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed } from "vue";
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import { userPage, acct } from "@/filters/user";
|
||||
import { acct, userPage } from "@/filters/user";
|
||||
import * as os from "@/os";
|
||||
import { i18n } from "@/i18n";
|
||||
import { definePageMetadata } from "@/scripts/page-metadata";
|
||||
import { $i } from "@/account";
|
||||
import { globalEvents } from "@/events";
|
||||
|
||||
const paginationComponent = ref<InstanceType<typeof MkPagination>>();
|
||||
|
||||
const pagination = {
|
||||
endpoint: "following/requests/list" as const,
|
||||
limit: 10,
|
||||
noPaging: true,
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
globalEvents.on("followeeProcessed", () =>
|
||||
paginationComponent.value.reload()
|
||||
);
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
globalEvents.off("followeeProcessed", () =>
|
||||
paginationComponent.value.reload()
|
||||
);
|
||||
});
|
||||
|
||||
function accept(user) {
|
||||
os.api("following/requests/accept", { userId: user.id }).then(() => {
|
||||
paginationComponent.value.reload();
|
||||
globalEvents.emit("followeeProcessed", user);
|
||||
});
|
||||
}
|
||||
|
||||
function reject(user) {
|
||||
os.api("following/requests/reject", { userId: user.id }).then(() => {
|
||||
paginationComponent.value.reload();
|
||||
globalEvents.emit("followeeProcessed", user);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,20 @@
|
|||
class="followed"
|
||||
>{{ i18n.ts.followsYou }}</span
|
||||
>
|
||||
<span
|
||||
v-if="
|
||||
$i &&
|
||||
$i.id != user.id &&
|
||||
user.hasPendingFollowRequestToYou
|
||||
"
|
||||
class="followed"
|
||||
>{{ i18n.ts.followRequestYou }}:
|
||||
<MkFollowApproveButton
|
||||
:user="user"
|
||||
@refresh="emit('refresh')"
|
||||
class="koudoku"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<span class="username"
|
||||
|
@ -369,7 +383,7 @@ import { getScrollPosition } from "@/scripts/scroll";
|
|||
import { userPage } from "@/filters/user";
|
||||
import { i18n } from "@/i18n";
|
||||
import { $i } from "@/account";
|
||||
import * as os from "@/os";
|
||||
import MkFollowApproveButton from "@/components/MkFollowApproveButton.vue";
|
||||
|
||||
const XPhotos = defineAsyncComponent(() => import("./index.photos.vue"));
|
||||
const XActivity = defineAsyncComponent(() => import("./index.activity.vue"));
|
||||
|
@ -382,14 +396,6 @@ const props = withDefaults(
|
|||
{}
|
||||
);
|
||||
|
||||
function accept(user) {
|
||||
os.api("following/requests/accept", { userId: user.id });
|
||||
}
|
||||
|
||||
function reject(user) {
|
||||
os.api("following/requests/reject", { userId: user.id }).then();
|
||||
}
|
||||
|
||||
let parallaxAnimationId = $ref<null | number>(null);
|
||||
let narrow = $ref<null | boolean>(null);
|
||||
let rootEl = $ref<null | HTMLElement>(null);
|
||||
|
|
Loading…
Reference in New Issue