2022-12-07 05:45:05 +00:00
|
|
|
<script>
|
2022-12-07 08:10:26 +00:00
|
|
|
import { mdiArrowLeft, mdiMagnify, mdiClose, mdiPlus } from "@mdi/js";
|
|
|
|
import { useVuelidate } from "@vuelidate/core";
|
|
|
|
import { helpers, required } from "@vuelidate/validators";
|
|
|
|
import { debounce, some, map } from "lodash-es";
|
2022-12-07 05:45:05 +00:00
|
|
|
import { login } from "masto";
|
|
|
|
import { webfinger } from "../assets/utils";
|
|
|
|
|
|
|
|
export default {
|
2022-12-07 08:10:26 +00:00
|
|
|
setup() {
|
|
|
|
return {
|
|
|
|
v$: useVuelidate(),
|
|
|
|
};
|
|
|
|
},
|
2022-12-07 05:45:05 +00:00
|
|
|
created() {
|
|
|
|
this.cohostSearch = debounce(this.search, 1000);
|
|
|
|
},
|
|
|
|
unmounted() {
|
|
|
|
this.cohostSearch.cancel();
|
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
mdiArrowLeft,
|
|
|
|
mdiMagnify,
|
|
|
|
mdiClose,
|
2022-12-07 08:10:26 +00:00
|
|
|
mdiPlus,
|
2022-12-07 05:45:05 +00:00
|
|
|
title: "",
|
|
|
|
description: "",
|
2022-12-07 08:10:26 +00:00
|
|
|
cohosts: [],
|
2022-12-07 05:45:05 +00:00
|
|
|
relationship: "everyone",
|
|
|
|
relOptions: [
|
|
|
|
{ title: "制限なし", value: "everyone" },
|
|
|
|
{ title: "フォロー限定", value: "following" },
|
|
|
|
{ title: "フォロワー限定", value: "follower" },
|
|
|
|
{ title: "フォローまたはフォロワー限定", value: "knows" },
|
|
|
|
{ title: "相互フォロー限定", value: "mutual" },
|
|
|
|
],
|
2022-12-07 08:10:26 +00:00
|
|
|
scheduledAt: null,
|
|
|
|
searchResult: null,
|
2022-12-07 05:45:05 +00:00
|
|
|
searchQuery: "",
|
|
|
|
isCandiadateLoading: false,
|
2022-12-07 08:10:26 +00:00
|
|
|
searchError: {
|
|
|
|
enabled: false,
|
|
|
|
message: "",
|
|
|
|
timeout: 5000,
|
|
|
|
colour: "",
|
|
|
|
},
|
2022-12-07 05:45:05 +00:00
|
|
|
};
|
|
|
|
},
|
2022-12-07 08:10:26 +00:00
|
|
|
validations() {
|
|
|
|
return {
|
|
|
|
title: {
|
|
|
|
required: helpers.withMessage("部屋の名前を入力してください", required),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
titleErrors() {
|
|
|
|
const errors = this.v$.title.$errors;
|
|
|
|
const messages = map(errors, (e) => e.$message);
|
|
|
|
return messages;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
watch: {
|
|
|
|
searchQuery(val) {
|
|
|
|
this.isCandiadateLoading = false;
|
|
|
|
if (!val) return;
|
|
|
|
if (some(this.cohosts, { finger: val })) {
|
|
|
|
this.searchError.message = "すでに追加済みです";
|
|
|
|
this.searchError.colour = "warning";
|
|
|
|
this.searchError.enabled = true;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.isCandiadateLoading = true;
|
|
|
|
this.cohostSearch(val);
|
|
|
|
},
|
|
|
|
},
|
2022-12-07 05:45:05 +00:00
|
|
|
methods: {
|
|
|
|
async search(val) {
|
2022-12-07 08:10:26 +00:00
|
|
|
const finger = val.split("@");
|
|
|
|
if (finger.length < 2) return;
|
|
|
|
else if (finger.length === 3) {
|
|
|
|
finger.splice(0, 1);
|
|
|
|
this.searchQuery = finger.join("@");
|
|
|
|
}
|
2022-12-07 05:45:05 +00:00
|
|
|
try {
|
2022-12-07 08:10:26 +00:00
|
|
|
const url = new URL(`https://${finger[1]}`);
|
|
|
|
const client = await login({ url: url.toString(), disableVersionCheck: true });
|
|
|
|
const user = await client.accounts.lookup({ acct: finger[0] });
|
|
|
|
user.finger = webfinger(user);
|
|
|
|
this.searchResult = user;
|
|
|
|
} catch (error) {
|
|
|
|
if (error.isMastoError && error.statusCode === 404) {
|
|
|
|
this.searchError.message = `${val} が見つかりません`;
|
|
|
|
this.searchError.colour = "error";
|
|
|
|
this.searchError.enabled = true;
|
|
|
|
}
|
2022-12-07 05:45:05 +00:00
|
|
|
} finally {
|
|
|
|
this.isCandiadateLoading = false;
|
|
|
|
}
|
|
|
|
},
|
2022-12-07 08:10:26 +00:00
|
|
|
onResultClick() {
|
|
|
|
this.cohosts.push(this.searchResult);
|
|
|
|
this.searchResult = null;
|
|
|
|
this.searchQuery = "";
|
|
|
|
},
|
|
|
|
webfinger,
|
2022-12-07 05:45:05 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<main>
|
|
|
|
<div>
|
|
|
|
<v-btn class="ma-2" variant="text" color="blue" :to="{ name: 'home' }">
|
|
|
|
<v-icon start :icon="mdiArrowLeft"></v-icon>
|
|
|
|
戻る
|
|
|
|
</v-btn>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-snackbar
|
|
|
|
v-model="searchError.enabled"
|
|
|
|
color="error"
|
|
|
|
:timeout="searchError.timeout"
|
|
|
|
>
|
|
|
|
{{ searchError.message }}
|
|
|
|
</v-snackbar>
|
2022-12-07 05:45:05 +00:00
|
|
|
<v-card>
|
|
|
|
<v-card-title class="text-center">部屋を新規作成</v-card-title>
|
|
|
|
<v-card-text>
|
|
|
|
<v-form>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-text-field
|
|
|
|
v-model="title"
|
|
|
|
label="タイトル"
|
|
|
|
:error-messages="titleErrors"
|
|
|
|
required
|
|
|
|
@input="v$.title.$touch()"
|
|
|
|
@blur="v$.title.$touch()"
|
|
|
|
></v-text-field>
|
2022-12-07 05:45:05 +00:00
|
|
|
<v-textarea
|
|
|
|
auto-grow
|
|
|
|
v-model="description"
|
|
|
|
rows="2"
|
|
|
|
label="説明"
|
|
|
|
></v-textarea>
|
|
|
|
<v-select
|
|
|
|
:items="relOptions"
|
|
|
|
label="入室制限"
|
|
|
|
v-model="relationship"
|
|
|
|
disabled
|
|
|
|
:messages="['今後のアップデートで追加予定']"
|
|
|
|
></v-select>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-text-field
|
|
|
|
type="datetime-local"
|
|
|
|
v-model="scheduledAt"
|
|
|
|
label="開始予約"
|
|
|
|
disabled
|
|
|
|
:messages="['今後のアップデートで追加予定']"
|
|
|
|
></v-text-field>
|
|
|
|
<v-card class="mt-3" variant="outlined">
|
2022-12-07 05:45:05 +00:00
|
|
|
<v-card-title class="text-subtitle-1">共同ホスト</v-card-title>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-card-text v-if="cohosts.length > 0 || searchResult">
|
|
|
|
<div v-if="cohosts.length > 0">
|
2022-12-07 05:45:05 +00:00
|
|
|
<v-list lines="two" variant="tonal">
|
|
|
|
<v-list-item
|
|
|
|
v-for="(cohost, index) in cohosts"
|
|
|
|
:key="cohost.url"
|
|
|
|
:title="cohost.displayName"
|
2022-12-07 08:10:26 +00:00
|
|
|
class="my-1"
|
2022-12-07 05:45:05 +00:00
|
|
|
rounded
|
|
|
|
>
|
|
|
|
<template v-slot:prepend>
|
|
|
|
<v-avatar class="rounded">
|
|
|
|
<v-img :src="cohost.avatar"></v-img>
|
|
|
|
</v-avatar>
|
|
|
|
</template>
|
|
|
|
<template v-slot:subtitle>
|
|
|
|
{{ webfinger(cohost) }}
|
|
|
|
</template>
|
|
|
|
<template v-slot:append>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-btn
|
|
|
|
variant="text"
|
|
|
|
size="small"
|
|
|
|
:icon="mdiClose"
|
|
|
|
@click="
|
|
|
|
() => {
|
|
|
|
cohosts.splice(index, 1);
|
|
|
|
}
|
|
|
|
"
|
|
|
|
></v-btn>
|
2022-12-07 05:45:05 +00:00
|
|
|
</template>
|
|
|
|
</v-list-item>
|
|
|
|
</v-list>
|
|
|
|
</div>
|
2022-12-07 08:10:26 +00:00
|
|
|
<div v-if="searchResult">
|
2022-12-07 05:45:05 +00:00
|
|
|
<v-divider></v-divider>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-list lines="two">
|
|
|
|
<v-list-item
|
|
|
|
:key="0"
|
|
|
|
:value="searchResult.acct"
|
|
|
|
:title="searchResult.displayName"
|
|
|
|
@click="onResultClick"
|
|
|
|
>
|
2022-12-07 05:45:05 +00:00
|
|
|
<template v-slot:prepend>
|
|
|
|
<v-avatar class="rounded">
|
|
|
|
<v-img :src="searchResult.avatar"></v-img>
|
|
|
|
</v-avatar>
|
|
|
|
</template>
|
2022-12-07 08:10:26 +00:00
|
|
|
<template v-slot:append>
|
|
|
|
<v-btn
|
|
|
|
size="small"
|
|
|
|
variant="plain"
|
|
|
|
:icon="mdiPlus"
|
|
|
|
></v-btn>
|
|
|
|
</template>
|
2022-12-07 05:45:05 +00:00
|
|
|
<v-list-item-subtitle>
|
|
|
|
{{ webfinger(searchResult) }}
|
|
|
|
</v-list-item-subtitle>
|
|
|
|
</v-list-item>
|
|
|
|
</v-list>
|
|
|
|
</div>
|
|
|
|
</v-card-text>
|
|
|
|
<v-card-actions>
|
|
|
|
<v-text-field
|
|
|
|
density="compact"
|
|
|
|
v-model="searchQuery"
|
2022-12-07 08:10:26 +00:00
|
|
|
type="email"
|
2022-12-07 05:45:05 +00:00
|
|
|
:prepend-inner-icon="mdiMagnify"
|
|
|
|
single-line
|
|
|
|
hide-details
|
|
|
|
clearable
|
2022-12-07 08:10:26 +00:00
|
|
|
:error="searchError.enabled"
|
2022-12-07 05:45:05 +00:00
|
|
|
:loading="isCandiadateLoading"
|
|
|
|
placeholder="user@mastodon.example"
|
|
|
|
>
|
|
|
|
</v-text-field>
|
|
|
|
</v-card-actions>
|
|
|
|
</v-card>
|
|
|
|
</v-form>
|
|
|
|
</v-card-text>
|
2022-12-07 08:10:26 +00:00
|
|
|
<v-card-actions>
|
|
|
|
<v-btn block color="indigo" variant="flat" >
|
|
|
|
作成
|
|
|
|
</v-btn>
|
|
|
|
</v-card-actions>
|
2022-12-07 05:45:05 +00:00
|
|
|
</v-card>
|
|
|
|
</div>
|
|
|
|
</main>
|
|
|
|
</template>
|