色々
This commit is contained in:
@@ -7,21 +7,42 @@
|
||||
|
||||
<div class="modals-container" />
|
||||
|
||||
<main class="layout" v-if="serverInfo.success && account.success">
|
||||
<main class="layout">
|
||||
<div class="left-menu">
|
||||
<div :class='$route.path === "/" ? "isActive" : ""'>
|
||||
<img :src="serverInfo.icon" />
|
||||
</div>
|
||||
<RouterLink
|
||||
to="/"
|
||||
:class='$route.path === "/"
|
||||
? "isActive"
|
||||
: ""'
|
||||
>
|
||||
<img :src='"icon" in serverInfo
|
||||
? serverInfo.icon
|
||||
: "/assets/lynqchat.svg"'
|
||||
/>
|
||||
</RouterLink>
|
||||
|
||||
<div :class='$route.path === "/home" ? "isActive" : ""'>
|
||||
<Icon icon="material-symbols:home-rounded" />
|
||||
</div>
|
||||
<RouterLink
|
||||
v-for="community of communitys"
|
||||
:to="`/community/${community.id}`"
|
||||
:class='$route.path === `/community/${community.id}`
|
||||
? "isActive"
|
||||
: ""'
|
||||
>
|
||||
<img
|
||||
v-if="community.icon"
|
||||
:src="community.icon"
|
||||
/>
|
||||
<Icon
|
||||
v-else
|
||||
icon="material-symbols:groups-rounded"
|
||||
/>
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<div class="content-main">
|
||||
<div class="content-header">
|
||||
{{
|
||||
$route.meta.title
|
||||
title
|
||||
?? (serverInfo.success
|
||||
? serverInfo.name
|
||||
: null)
|
||||
@@ -61,7 +82,8 @@ main.layout {
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.left-menu div {
|
||||
.left-menu a {
|
||||
display: block;
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
border-radius: 0.5rem;
|
||||
@@ -71,19 +93,20 @@ main.layout {
|
||||
transition: background-color 200ms ease-out;
|
||||
}
|
||||
|
||||
.left-menu div * {
|
||||
.left-menu a * {
|
||||
font-size: 3rem;
|
||||
padding: 0.25rem;
|
||||
border-radius: 0.5rem;
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
color: var(--text-color);
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
object-fit: contain;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.left-menu div.isActive::before {
|
||||
.left-menu a.isActive::before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
@@ -96,8 +119,8 @@ main.layout {
|
||||
background-color: var(--text-color);
|
||||
}
|
||||
|
||||
.left-menu div:hover,
|
||||
.left-menu div.isActive {
|
||||
.left-menu a:hover,
|
||||
.left-menu a.isActive {
|
||||
background-color: var(--border-color);
|
||||
}
|
||||
|
||||
@@ -122,6 +145,7 @@ main.layout {
|
||||
}
|
||||
|
||||
.route-main {
|
||||
display: flex;
|
||||
padding: 1.25rem;
|
||||
padding-bottom: 0;
|
||||
overflow: scroll;
|
||||
@@ -156,16 +180,25 @@ main.layout {
|
||||
</style>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { RouterView, useRouter } from "vue-router";
|
||||
import routerStatus from "@/lib/router";
|
||||
import { RouterView, RouterLink, useRouter, useRoute } from "vue-router";
|
||||
import routerStatus, { title } from "@/lib/router";
|
||||
import { Icon } from "@iconify/vue";
|
||||
import Progress from "@/components/Progress.vue";
|
||||
import { account, serverInfo } from "@/lib/account";
|
||||
import { communitys, serverInfo } from "@/lib/account";
|
||||
import { onBeforeUnmount, onMounted, watch } from "vue";
|
||||
import { createModal } from "@/lib/modal";
|
||||
import ErrorModal from "@/components/Modal/Error.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
watch(route, () => {
|
||||
if (typeof route.meta.title === "string")
|
||||
title.value = route.meta.title;
|
||||
});
|
||||
|
||||
if (!serverInfo.value.success) {
|
||||
throw new Error();
|
||||
throw new Error("サーバー情報の取得に失敗しました。");
|
||||
}
|
||||
|
||||
if (!serverInfo.value.isInitialized) {
|
||||
@@ -175,4 +208,45 @@ if (!serverInfo.value.isInitialized) {
|
||||
if (!serverInfo.value.isFirstAdminExists) {
|
||||
router.replace("/setup/create-admin");
|
||||
}
|
||||
|
||||
function handleError(event: ErrorEvent | PromiseRejectionEvent) {
|
||||
let content = event instanceof PromiseRejectionEvent
|
||||
? event.reason
|
||||
: event;
|
||||
|
||||
if (content instanceof Error) {
|
||||
content = content.message;
|
||||
}
|
||||
|
||||
createModal({
|
||||
component: ErrorModal,
|
||||
props: {
|
||||
error: content ?? "不明なエラー",
|
||||
canClose: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
window.addEventListener("error", handleError);
|
||||
window.addEventListener("unhandledrejection", handleError);
|
||||
|
||||
if ("serviceWorker" in navigator) {
|
||||
const swFile = import.meta.env.MODE === "production"
|
||||
? "/sw.js"
|
||||
: "/dev-sw.js?dev-sw";
|
||||
|
||||
navigator.serviceWorker.register(swFile, {
|
||||
type: import.meta.env.MODE === "production"
|
||||
? "classic"
|
||||
: "module",
|
||||
scope: "/",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener("error", handleError);
|
||||
window.removeEventListener("unhandledrejection", handleError);
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user