show dialog after room creation

pull/6/head
Namekuji 2022-12-09 09:59:37 -05:00
rodzic 52c7587ce4
commit 544b0a54c1
8 zmienionych plików z 254 dodań i 35 usunięć

134
audon-fe/package-lock.json wygenerowano
Wyświetl plik

@ -10,6 +10,7 @@
"dependencies": {
"@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0",
"@vueuse/core": "^9.6.0",
"axios": "^1.2.0",
"livekit-client": "^1.5.0",
"lodash-es": "^4.17.21",
@ -234,6 +235,11 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz",
"integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g=="
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
},
"node_modules/@vitejs/plugin-vue": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz",
@ -466,6 +472,89 @@
"vuetify": "^3.0.0-beta.4"
}
},
"node_modules/@vueuse/core": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz",
"integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.6.0",
"@vueuse/shared": "9.6.0",
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/core/node_modules/vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vueuse/metadata": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz",
"integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz",
"integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==",
"dependencies": {
"vue-demi": "*"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared/node_modules/vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
@ -3111,6 +3200,11 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.11.tgz",
"integrity": "sha512-KJ021B1nlQUBLopzZmPBVuGU9un7WJd/W4ya7Ih02B4Uwky5Nja0yGYav2EfYIk0RR2Q9oVhf60S2XR1BCWJ2g=="
},
"@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
},
"@vitejs/plugin-vue": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-3.2.0.tgz",
@ -3274,6 +3368,46 @@
"upath": "^2.0.1"
}
},
"@vueuse/core": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.6.0.tgz",
"integrity": "sha512-qGUcjKQXHgN+jqXEgpeZGoxdCbIDCdVPz3QiF1uyecVGbMuM63o96I1GjYx5zskKgRI0FKSNsVWM7rwrRMTf6A==",
"requires": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.6.0",
"@vueuse/shared": "9.6.0",
"vue-demi": "*"
},
"dependencies": {
"vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"requires": {}
}
}
},
"@vueuse/metadata": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.6.0.tgz",
"integrity": "sha512-sIC8R+kWkIdpi5X2z2Gk8TRYzmczDwHRhEFfCu2P+XW2JdPoXrziqsGpDDsN7ykBx4ilwieS7JUIweVGhvZ93w=="
},
"@vueuse/shared": {
"version": "9.6.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.6.0.tgz",
"integrity": "sha512-/eDchxYYhkHnFyrb00t90UfjCx94kRHxc7J1GtBCqCG4HyPMX+krV9XJgVtWIsAMaxKVU4fC8NSUviG1JkwhUQ==",
"requires": {
"vue-demi": "*"
},
"dependencies": {
"vue-demi": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.13.11.tgz",
"integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
"requires": {}
}
}
},
"acorn": {
"version": "8.8.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",

Wyświetl plik

@ -11,6 +11,7 @@
"dependencies": {
"@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0",
"@vueuse/core": "^9.6.0",
"axios": "^1.2.0",
"livekit-client": "^1.5.0",
"lodash-es": "^4.17.21",

Wyświetl plik

@ -1,5 +1,5 @@
<script setup>
import { RouterView } from 'vue-router'
import { RouterView, RouterLink } from 'vue-router'
</script>
<template>
@ -7,7 +7,7 @@ import { RouterView } from 'vue-router'
<v-system-bar window>
<v-row>
<v-col class="text-center">
<h2>Audon</h2>
<h2><RouterLink :to="{name: 'home'}" style="text-decoration: inherit; color: inherit;">Audon</RouterLink></h2>
</v-col>
</v-row>
<div style="position:fixed">v0.1.0-dev</div>

Wyświetl plik

@ -49,10 +49,11 @@ router.beforeEach(async (to) => {
}
}
});
router.afterEach((to) => {
router.afterEach((to, from) => {
const donStore = useMastodonStore();
if (!to.meta.noauth && !donStore.authorized) {
router.push({ name: "login" }); // need to push in afterEach to get nonempty lastPath in LoginView.vue
const query = to.name !== "home" ? {l: to.path} : {};
router.push({ name: "login", query }); // need to push in afterEach to get nonempty lastPath in LoginView.vue
} else if (to.name === "login" && donStore.authorized) {
router.replace({ name: "home" });
}

Wyświetl plik

@ -1,9 +1,18 @@
<script>
import { mdiArrowLeft, mdiMagnify, mdiClose, mdiPlus } from "@mdi/js";
import {
mdiArrowLeft,
mdiMagnify,
mdiClose,
mdiPlus,
mdiClipboardCheck,
mdiClipboardEdit,
mdiMastodon,
} from "@mdi/js";
import { useVuelidate } from "@vuelidate/core";
import { useClipboard } from "@vueuse/core";
import { useMastodonStore } from "../stores/mastodon";
import { helpers, required } from "@vuelidate/validators";
import { debounce, some, map } from "lodash-es";
import { debounce, some, map, truncate, trim } from "lodash-es";
import { login } from "masto";
import { webfinger } from "../assets/utils";
import axios from "axios";
@ -13,6 +22,7 @@ export default {
return {
v$: useVuelidate(),
donStore: useMastodonStore(),
clipboard: useClipboard(),
};
},
created() {
@ -23,6 +33,9 @@ export default {
},
data() {
return {
mdiMastodon,
mdiClipboardCheck,
mdiClipboardEdit,
mdiArrowLeft,
mdiMagnify,
mdiClose,
@ -37,6 +50,7 @@ export default {
{ title: "フォロワー限定", value: "follower" },
{ title: "フォローまたはフォロワー限定", value: "knows" },
{ title: "相互フォロー限定", value: "mutual" },
{ title: "非公開", value: "private" },
],
scheduledAt: null,
searchResult: null,
@ -49,6 +63,7 @@ export default {
colour: "",
},
isSubmissionLoading: false,
createdRoomID: "",
};
},
validations() {
@ -64,6 +79,25 @@ export default {
const messages = map(errors, (e) => e.$message);
return messages;
},
isDialogActive() {
return this.createdRoomID !== "";
},
roomURL() {
const url = new URL(window.location.href);
return `${url.origin}/r/${this.createdRoomID}`;
},
shareURL() {
const donURL = this.donStore.userinfo?.url;
if (!donURL) return "";
const url = new URL(donURL);
const texts = [
`Audon で部屋を作りました!\n視聴リンク ${this.roomURL}`,
`タイトル:${this.title}`,
];
if (this.description)
texts.push(truncate(this.description, { length: 200 }));
return encodeURI(`${url.origin}/share?text=${texts.join("\n\n")}`);
},
},
watch: {
searchQuery(val) {
@ -115,8 +149,13 @@ export default {
this.searchResult = null;
this.searchQuery = "";
},
onShareClick() {
window.open(this.shareURL, "Audon Share", "width=400,height=600");
},
webfinger,
async onSubmit() {
this.title = trim(this.title);
this.description = trim(this.description);
const isFormCorrect = await this.v$.$validate();
if (!isFormCorrect) {
return;
@ -133,7 +172,8 @@ export default {
try {
const resp = await axios.post("/api/room", payload);
if (resp.status === 201) {
this.$router.push({ name: "room", params: { id: resp.data } });
this.createdRoomID = resp.data;
// this.$router.push({ name: "room", params: { id: resp.data } });
}
} catch (error) {
this.searchError.message = `Error: ${error}`;
@ -148,6 +188,47 @@ export default {
</script>
<template>
<v-dialog v-model="isDialogActive" persistent max-width="700">
<v-alert
type="success"
color="blue-gray"
title="お部屋の用意ができました!"
>
<div>
{{ title }} を作りました参加者に以下の URL を共有してください
</div>
<div class="my-3">
<h3 style="word-break: break-all;">{{ roomURL }}</h3>
</div>
<div>
<v-btn
:prepend-icon="mdiMastodon"
class="mr-3"
@click="onShareClick"
color="#563ACC"
size="small"
>シェア</v-btn
>
<v-btn
@click="clipboard.copy(roomURL)"
color="lime"
size="small"
:prepend-icon="
clipboard.copied.value ? mdiClipboardCheck : mdiClipboardEdit
"
>{{ clipboard.copied.value ? "コピーしました" : "コピー" }}</v-btn
>
</div>
<div class="text-center mt-10 mb-1">
<v-btn
color="indigo"
:to="{ name: 'room', params: { id: createdRoomID } }"
size="large"
>入室</v-btn
>
</div>
</v-alert>
</v-dialog>
<main>
<div>
<v-btn class="ma-2" variant="text" color="blue" :to="{ name: 'home' }">

Wyświetl plik

@ -16,13 +16,8 @@ export default {
return {
server: "",
serverErr: "",
lastPath: null,
};
},
mounted() {
const from = this.$router.options.history.state.back;
this.lastPath = from === this.$route.path ? "/" : from;
},
validations() {
return {
server: {
@ -35,6 +30,9 @@ export default {
};
},
computed: {
lastPath() {
return this.$route.query.l ?? "";
},
serverErrors() {
const errors = this.v$.server.$errors;
const messages = map(errors, (e) => e.$message);

Wyświetl plik

@ -10,14 +10,9 @@ import {
mdiPhoneRemove,
mdiMicrophoneQuestion,
mdiDoorClosed,
mdiVolumeOff
mdiVolumeOff,
} from "@mdi/js";
import {
Room,
RoomEvent,
Track,
DisconnectReason,
} from "livekit-client";
import { Room, RoomEvent, Track, DisconnectReason } from "livekit-client";
import { login } from "masto";
export default {
@ -90,7 +85,7 @@ export default {
const myInfo = this.donStore.userinfo;
if (!myInfo) return false;
return this.isCohost({remote_id: myInfo.id , remote_url: myInfo.url});
return this.isCohost({ remote_id: myInfo.id, remote_url: myInfo.url });
},
micStatusIcon() {
if (!this.micGranted) {
@ -160,7 +155,7 @@ export default {
if (!room.canPlaybackAudio) {
// FIXME: popup a dialog to ask user to allow audio playback
// alert("autoplay not permitted");
self.autoplayDisabled = true
self.autoplayDisabled = true;
}
})
.on(RoomEvent.Disconnected, (reason) => {
@ -207,17 +202,23 @@ export default {
}
}
} catch (error) {
if (error.response?.status === 404) {
pushNotFound(this.$route);
} else if (error.response?.status === 406) {
alert(
"他のデバイスで入室済みです。切断された場合はしばらく待ってからやり直してください。"
);
this.$router.push({ name: "home" });
} else {
// FIXME: error handling
alert(error);
this.$router.push({ name: "home" });
switch (error.response?.status) {
case 404:
pushNotFound(this.$route);
break;
case 406:
alert(
"他のデバイスで入室済みです。切断された場合はしばらく待ってからやり直してください。"
);
this.$router.push({ name: "home" });
break;
case 410:
alert("この部屋はすでに閉じられています。");
this.$router.push({ name: "home" });
break;
default:
alert(error);
this.$router.push({ name: "home" });
}
} finally {
this.loading = false;
@ -309,7 +310,7 @@ export default {
alert("接続できませんでした。退室します。");
await this.roomClient.disconnect();
}
}
},
},
};
</script>
@ -317,7 +318,9 @@ export default {
<template>
<v-dialog v-model="autoplayDisabled" max-width="500" persistent>
<v-alert color="indigo">
<div class="mb-5">ブラウザの設定により無音になっています続行するには視聴を始めるボタンを押してください</div>
<div class="mb-5">
ブラウザの設定により無音になっています続行するには視聴を始めるボタンを押してください
</div>
<div class="text-center mb-3">
<v-btn color="gray" @click="onStartListening"></v-btn>
</div>

Wyświetl plik

@ -134,7 +134,8 @@ func main() {
api.DELETE("/room/:id", closeRoomHandler)
api.PATCH("/room/:room/:user", updatePermissionHandler)
// e.Static("/", "audon-fe/dist/assets")
e.Static("/assets", "audon-fe/dist/assets")
e.File("/*", "audon-fe/dist/index.html")
e.Logger.Debug(e.Start(":1323"))
}