mirror of
https://iceshrimp.dev/Crimekillz/jointrashposs.git
synced 2024-11-22 00:43:50 +01:00
(add) サーバー一覧をリスト表示できるように
This commit is contained in:
parent
265f93a91c
commit
27b66197bb
14
assets/css/bootstrap-forms.scss
vendored
14
assets/css/bootstrap-forms.scss
vendored
@ -27,4 +27,16 @@ $primary: #86b300;
|
||||
|
||||
// button
|
||||
@import "bootstrap/scss/buttons";
|
||||
@import "bootstrap/scss/button-group";
|
||||
@import "bootstrap/scss/button-group";
|
||||
|
||||
// Overrides
|
||||
.btn-outline-primary {
|
||||
--bs-btn-hover-color: #fff;
|
||||
--bs-btn-active-color: #fff;
|
||||
}
|
||||
.btn-primary {
|
||||
--bs-btn-color: #fff;
|
||||
--bs-btn-hover-color: #fff;
|
||||
--bs-btn-active-color: #fff;
|
||||
--bs-btn-disabled-color: #fff;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button class="btn btn-primary inline-block mb-4 !text-white hover:!text-white" @click="click()">
|
||||
<button class="btn btn-primary inline-block mb-4" @click="click()">
|
||||
{{ isEnabledAiChanMode ? '藍モードを無効にする' : '藍モードを有効にする' }}
|
||||
</button>
|
||||
</template>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button class="btn btn-outline-primary hover:!text-white focus-visible:!text-white" @click="copy">
|
||||
<button class="btn btn-outline-primary" @click="copy">
|
||||
<CopyIco class="w-4 h-4" v-if="!copied" />
|
||||
<CheckIco class="w-4 h-4" v-else />
|
||||
</button>
|
||||
|
@ -58,7 +58,7 @@
|
||||
<label class="form-label inline-block" for="userDefinedInstanceInput">{{ $t('_share.domain') }}</label>
|
||||
<div class="input-group">
|
||||
<input id="userDefinedInstanceInput" class="form-control" autocomplete="off" placeholder="misskey.example.com" v-model="userDefinedInstanceInput" :disabled="iFetching" />
|
||||
<button type="submit" class="btn btn-primary !text-white hover:!text-white focus-visible:!text-white" :disabled="iFetching"><PlusIco class="h-4 w-4 stroke-1 stroke-current" /></button>
|
||||
<button type="submit" class="btn btn-primary" :disabled="iFetching"><PlusIco class="h-4 w-4 stroke-1 stroke-current" /></button>
|
||||
</div>
|
||||
<div class="form-text">{{ $t('_share.compatibleWith') }}</div>
|
||||
</form>
|
||||
|
@ -22,7 +22,7 @@
|
||||
<label class="form-label" for="query">{{ $t('_servers._search.query') }}</label>
|
||||
<div class="input-group">
|
||||
<input class="form-control" type="search" autocomplete="off" id="query" v-model="f_query_partial" />
|
||||
<button type="submit" class="btn btn-outline-primary hover:!text-white">
|
||||
<button type="submit" class="btn btn-outline-primary">
|
||||
<SearchIco class="stroke-[0.5] stroke-current" />
|
||||
</button>
|
||||
</div>
|
||||
@ -43,7 +43,7 @@
|
||||
<option value="notesCount">{{ $t('_servers._search.notesCount') }}</option>
|
||||
<option value="usersCount">{{ $t('_servers._search.usersCount') }}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-primary hover:!text-white" @click="switchOrder()">
|
||||
<button class="btn btn-outline-primary" @click="switchOrder()">
|
||||
<SortDownIco v-if="f_order === 'desc'" class="stroke-[0.5] stroke-current" />
|
||||
<SortUpIco v-else class="stroke-[0.5] stroke-current" />
|
||||
</button>
|
||||
@ -70,24 +70,56 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="pt-2 text-xl font-bold">{{ $t('_servers._view.title') }}</h3>
|
||||
<div class="btn-group w-full" role="group">
|
||||
<input type="radio" class="btn-check" name="btnradio" id="btnradio1" autocomplete="off" value="grid" v-model="v_view">
|
||||
<label class="btn btn-outline-primary truncate" for="btnradio1"><GridIco class="mr-1" />{{ $t('_servers._view.grid') }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="btnradio" id="btnradio2" autocomplete="off" value="list" v-model="v_view">
|
||||
<label class="btn btn-outline-primary truncate" for="btnradio2"><ListIco class="mr-1" />{{ $t('_servers._view.list') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
<div>
|
||||
<div class="grid gap-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2">
|
||||
<ServersItem v-if="filteredInstances.length > 0" v-for="item in filteredInstances.slice(0, f_limit)" :instance="item" />
|
||||
<div v-else-if="data" class="rounded-lg p-6 min-h-[40vh] flex items-center sm:col-span-2 md:col-span-2 lg:col-span-2 bg-slate-100 dark:bg-slate-800">
|
||||
<div
|
||||
class="grid gap-4"
|
||||
:class="[
|
||||
(v_view === 'grid') && 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-2',
|
||||
(v_view === 'list') && 'grid-cols-1',
|
||||
]"
|
||||
>
|
||||
<ServersItem v-if="filteredInstances.length > 0" v-for="item in filteredInstances.slice(0, f_limit)" :instance="item" :view="v_view" />
|
||||
<div
|
||||
v-else-if="data"
|
||||
class="rounded-lg p-6 min-h-[40vh] flex items-center bg-slate-100 dark:bg-slate-800"
|
||||
:class="[
|
||||
(v_view === 'grid') && 'sm:col-span-2 md:col-span-2 lg:col-span-2'
|
||||
]"
|
||||
>
|
||||
<div class="mx-auto text-center">
|
||||
<img src="https://xn--931a.moe/assets/info.jpg" class="rounded-lg mx-auto mb-4" />
|
||||
<p class="max-w-xs">{{ $t('_servers._list.notFound') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="rounded-lg p-6 min-h-[40vh] flex items-center sm:col-span-2 md:col-span-2 lg:col-span-2 bg-slate-100 dark:bg-slate-800">
|
||||
<div
|
||||
v-else
|
||||
class="rounded-lg p-6 min-h-[40vh] flex items-center bg-slate-100 dark:bg-slate-800"
|
||||
:class="[
|
||||
(v_view === 'grid') && 'sm:col-span-2 md:col-span-2 lg:col-span-2'
|
||||
]"
|
||||
>
|
||||
<div class="mx-auto text-center">
|
||||
<MkLoading class="mx-auto"></MkLoading>
|
||||
<p class="max-w-xs">{{ $t('loading') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<button v-if="f_limit < filteredInstances.length" @click="f_limit += 24" class="btn btn-outline-primary btn-lg hover:!text-white block sm:col-span-2 md:col-span-3 lg:col-span-2 px-4">
|
||||
<button
|
||||
v-if="f_limit < filteredInstances.length" @click="f_limit += 24"
|
||||
class="btn btn-outline-primary btn-lg block px-4"
|
||||
:class="[
|
||||
(v_view === 'grid') && 'sm:col-span-2 md:col-span-2 lg:col-span-2'
|
||||
]"
|
||||
>
|
||||
<ArrowIco class="mr-1" />{{ $t('_servers._list.showMore') }}
|
||||
</button>
|
||||
</div>
|
||||
@ -105,6 +137,8 @@ import SortUpIco from 'bi/sort-down-alt.svg';
|
||||
import SortDownIco from 'bi/sort-down.svg';
|
||||
import ArrowIco from 'bi/arrow-down-circle.svg';
|
||||
import XIco from 'bi/x.svg';
|
||||
import GridIco from 'bi/grid-3x2-gap.svg';
|
||||
import ListIco from 'bi/view-stacked.svg';
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
const route = useRoute();
|
||||
@ -114,7 +148,6 @@ const emits = defineEmits<{
|
||||
|
||||
// ▼スマホ用ソート▼
|
||||
const sortOpen = ref(false);
|
||||
|
||||
// ▲スマホ用ソート▲
|
||||
|
||||
// ▼フォームデータ初期化▼
|
||||
@ -123,6 +156,7 @@ type MiHubSFStorage = {
|
||||
f_orderBy: 'recomendded' | 'notesCount' | 'notesPer15Days' | 'usersCount';
|
||||
f_order: 'asc' | 'desc';
|
||||
f_registerAcceptance: 'public' | 'inviteOnly' | null;
|
||||
v_view: 'grid' | 'list';
|
||||
};
|
||||
|
||||
let savedSettings: MiHubSFStorage | null = null;
|
||||
@ -139,10 +173,12 @@ const f_order = ref<MiHubSFStorage['f_order']>(savedSettings?.f_order ?? 'desc')
|
||||
const f_registerAcceptance = ref<MiHubSFStorage['f_registerAcceptance']>(savedSettings?.f_registerAcceptance || null);
|
||||
|
||||
const f_limit = ref<number>(24);
|
||||
|
||||
const v_view = ref<MiHubSFStorage['v_view']>(savedSettings?.v_view ?? 'grid');
|
||||
// ▲フォームデータ初期化▲
|
||||
|
||||
// ▼フォームデータ保存処理▼
|
||||
watch([f_langs, f_orderBy, f_order, f_registerAcceptance], (to, from) => {
|
||||
watch([f_langs, f_orderBy, f_order, f_registerAcceptance, v_view], (to, from) => {
|
||||
f_limit.value = 24;
|
||||
|
||||
const newSettings: MiHubSFStorage = {
|
||||
@ -150,6 +186,7 @@ watch([f_langs, f_orderBy, f_order, f_registerAcceptance], (to, from) => {
|
||||
f_orderBy: to[1],
|
||||
f_order: to[2],
|
||||
f_registerAcceptance: to[3],
|
||||
v_view: to[4],
|
||||
};
|
||||
|
||||
if (process.client) {
|
||||
|
@ -1,36 +1,78 @@
|
||||
<template>
|
||||
<div class="border border-gray-300 dark:border-gray-800 dark:bg-slate-800 rounded-lg shadow-lg overflow-hidden focus-within:ring-2 ring-accent-500 ring-offset-2">
|
||||
<GNuxtLink :to="`https://${instance.url}`" target="_blank">
|
||||
<div class="relative aspect-video bg-gray-200 dark:bg-gray-600">
|
||||
<img v-if="instance.banner" :src="`https://instanceapp.misskey.page/instance-banners/${instance.url}.webp`" class="w-full h-full object-cover" />
|
||||
<img v-else-if="instance.background" :src="`https://instanceapp.misskey.page/instance-backgrounds/${instance.url}.webp`" class="w-full h-full object-cover" />
|
||||
<div class="absolute h-1/2 bottom-0 left-0 w-full bg-gradient-to-b from-transparent to-black text-white p-4 flex items-end">
|
||||
<GNuxtLink :to="`https://${instance.url}`" target="_blank" class="relative">
|
||||
<template v-if="view === 'grid'">
|
||||
<div class="relative aspect-video bg-gray-200 dark:bg-gray-600">
|
||||
<img v-if="instance.banner" loading="lazy" :src="`https://instanceapp.misskey.page/instance-banners/${instance.url}.webp`" class="w-full h-full object-cover" />
|
||||
<img v-else-if="instance.background" loading="lazy" :src="`https://instanceapp.misskey.page/instance-backgrounds/${instance.url}.webp`" class="w-full h-full object-cover" />
|
||||
<div class="absolute h-1/2 bottom-0 left-0 w-full bg-gradient-to-b from-transparent to-black text-white p-4 flex items-end">
|
||||
<div class="h-14 w-14 min-w-0 flex-shrink-0 mr-4">
|
||||
<img v-if="instance.icon" :src="`https://instanceapp.misskey.page/instance-icons/${instance.url}.webp`" class="w-full h-full rounded" />
|
||||
</div>
|
||||
<div class="min-w-0 flex flex-col justify-end">
|
||||
<h2 class="font-bold text-2xl whitespace-nowrap truncate">{{ instance.name }}</h2>
|
||||
<p class="opacity-90 text-sm truncate">{{ instance.url }} / v.{{ instance.nodeinfo?.software.version }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<p class="description h-12 mb-2">{{ instance.description }}</p>
|
||||
<div class="grid grid-cols-3 text-center">
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._statistics.notes') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalNotesCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._statistics.users') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalUsersCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._registerAcceptance.title') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.meta?.disableRegistration ? $t('_servers._registerAcceptance.inviteOnly') : $t('_servers._registerAcceptance.public')}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="view === 'list'">
|
||||
<div class="absolute h-full w-4/5 top-0 left-0 overflow-hidden">
|
||||
<img v-if="instance.banner" loading="lazy" :src="`https://instanceapp.misskey.page/instance-banners/${instance.url}.webp`" class="h-full w-full object-cover object-center opacity-40 blur-md" />
|
||||
<img v-else-if="instance.background" loading="lazy" :src="`https://instanceapp.misskey.page/instance-backgrounds/${instance.url}.webp`" class="h-full w-full object-cover object-center opacity-40 blur-md" />
|
||||
<div class="absolute top-0 left-0 h-full w-full bg-gradient-to-r from-transparent to-white dark:to-slate-800"></div>
|
||||
</div>
|
||||
<div class="relative flex w-full items-center p-2">
|
||||
<div class="h-14 w-14 min-w-0 flex-shrink-0 mr-4">
|
||||
<img v-if="instance.icon" :src="`https://instanceapp.misskey.page/instance-icons/${instance.url}.webp`" class="w-full h-full" />
|
||||
<img v-if="instance.icon" :src="`https://instanceapp.misskey.page/instance-icons/${instance.url}.webp`" class="w-full h-full rounded" />
|
||||
</div>
|
||||
<div class="min-w-0 flex flex-col justify-end">
|
||||
<h2 class="font-bold text-2xl whitespace-nowrap truncate">{{ instance.name }}</h2>
|
||||
<p class="opacity-90 text-sm truncate">{{ instance.url }} / v.{{ instance.nodeinfo?.software.version }}</p>
|
||||
<div class="truncate">
|
||||
<h2 class="font-bold text-xl whitespace-nowrap truncate">{{ instance.name }}</h2>
|
||||
<p class="opacity-90 hidden sm:block text-sm truncate">{{ instance.url }} / v.{{ instance.nodeinfo?.software.version }}</p>
|
||||
<p class="text-sm flex sm:hidden space-x-2">
|
||||
<dl class="flex space-x-1">
|
||||
<dt class="opacity-90">{{ $t('_servers._statistics.users') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalUsersCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl class="flex space-x-1">
|
||||
<dt class="opacity-90">{{ $t('_servers._registerAcceptance.title') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.meta?.disableRegistration ? $t('_servers._registerAcceptance.inviteOnly') : $t('_servers._registerAcceptance.public')}}</dd>
|
||||
</dl>
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-auto flex-shrink-0 hidden min-w-[17rem] sm:grid grid-cols-3 text-center">
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._statistics.notes') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalNotesCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._statistics.users') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalUsersCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._registerAcceptance.title') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.meta?.disableRegistration ? $t('_servers._registerAcceptance.inviteOnly') : $t('_servers._registerAcceptance.public')}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<p class="description h-12 mb-2">{{ instance.description }}</p>
|
||||
<div class="grid grid-cols-3 text-center">
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._statistics.notes') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalNotesCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._statistics.users') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.stats?.originalUsersCount.toLocaleString() }}</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="text-xs opacity-90">{{ $t('_servers._registerAcceptance.title') }}</dt>
|
||||
<dd class="font-bold text-accent-600">{{ instance.meta?.disableRegistration ? $t('_servers._registerAcceptance.inviteOnly') : $t('_servers._registerAcceptance.public')}}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</GNuxtLink>
|
||||
</div>
|
||||
</template>
|
||||
@ -38,9 +80,12 @@
|
||||
<script setup lang="ts">
|
||||
import type { InstanceItem } from '@/types/instances-info';
|
||||
|
||||
defineProps<{
|
||||
withDefaults(defineProps<{
|
||||
instance: InstanceItem;
|
||||
}>()
|
||||
view?: 'grid' | 'list';
|
||||
}>(), {
|
||||
view: 'grid',
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -130,6 +130,10 @@ _servers:
|
||||
_list:
|
||||
notFound: "指定された条件に合致するサーバーは見つかりませんでした。"
|
||||
showMore: "もっと見る"
|
||||
_view:
|
||||
title: "表示形式"
|
||||
list: "リスト"
|
||||
grid: "グリッド"
|
||||
|
||||
_docs:
|
||||
title: "ドキュメント"
|
||||
|
@ -11,7 +11,7 @@
|
||||
<label class="mb-1" for="aidToDateAid">aid / aidx</label>
|
||||
<input class="form-control" id="aidToDateAid" v-model="aidToDateAid" />
|
||||
<div class="my-2">
|
||||
<button class="btn btn-primary !text-white" @click="doAidToDate()">{{ $t('_aidConverter.aidToDate') }}</button>
|
||||
<button class="btn btn-primary" @click="doAidToDate()">{{ $t('_aidConverter.aidToDate') }}</button>
|
||||
</div>
|
||||
<div class="mb-2 p-4 rounded-lg border bg-white dark:bg-[#212529] border-gray-200 dark:border-gray-600">
|
||||
{{ aidToDateResult }}
|
||||
@ -26,7 +26,7 @@
|
||||
<option value="aidx">aidx</option>
|
||||
</select>
|
||||
<div class="my-2">
|
||||
<button class="btn btn-primary !text-white" @click="doDateToAid()">{{ $t('_aidConverter.dateToAid') }}</button>
|
||||
<button class="btn btn-primary" @click="doDateToAid()">{{ $t('_aidConverter.dateToAid') }}</button>
|
||||
</div>
|
||||
<div class="mb-2 p-4 rounded-lg border bg-white dark:bg-[#212529] border-gray-200 dark:border-gray-600">
|
||||
{{ dateToAidResult }}
|
||||
|
@ -33,7 +33,7 @@
|
||||
<label for="mfmPlaygroundDomain">{{ $t('_mfmPlayground.domain') }}</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="mfmPlaygroundDomain" v-model="mfmHost" />
|
||||
<GNuxtLink :to="shareURL" target="_blank" class="btn btn-primary !text-white">{{ $t('_mfmPlayground.noteIt') }}<SendIco class="ml-1" /></GNuxtLink>
|
||||
<GNuxtLink :to="shareURL" target="_blank" class="btn btn-primary">{{ $t('_mfmPlayground.noteIt') }}<SendIco class="ml-1" /></GNuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@ -42,7 +42,7 @@
|
||||
{{ $t('_mfmPlayground.clearEmojiCacheDescription') }}
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<button @click="clearEmojiCache()" class="btn w-full btn-outline-primary hover:!text-white">{{ $t('_mfmPlayground.clearEmojiCache') }}</button>
|
||||
<button @click="clearEmojiCache()" class="btn w-full btn-outline-primary">{{ $t('_mfmPlayground.clearEmojiCache') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user