summaryrefslogtreecommitdiff
path: root/packages/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/frontend/src')
-rw-r--r--packages/frontend/src/components/MkUserSelectDialog.vue28
-rw-r--r--packages/frontend/src/os.ts3
-rw-r--r--packages/frontend/src/pages/reversi/game.board.vue21
-rw-r--r--packages/frontend/src/pages/reversi/index.vue7
4 files changed, 39 insertions, 20 deletions
diff --git a/packages/frontend/src/components/MkUserSelectDialog.vue b/packages/frontend/src/components/MkUserSelectDialog.vue
index d7bd73aa8a..1846361108 100644
--- a/packages/frontend/src/components/MkUserSelectDialog.vue
+++ b/packages/frontend/src/components/MkUserSelectDialog.vue
@@ -16,7 +16,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header>{{ i18n.ts.selectUser }}</template>
<div>
<div :class="$style.form">
- <FormSplit :minWidth="170">
+ <MkInput v-if="localOnly" v-model="username" :autofocus="true" @update:modelValue="search">
+ <template #label>{{ i18n.ts.username }}</template>
+ <template #prefix>@</template>
+ </MkInput>
+ <FormSplit v-else :minWidth="170">
<MkInput v-model="username" :autofocus="true" @update:modelValue="search">
<template #label>{{ i18n.ts.username }}</template>
<template #prefix>@</template>
@@ -66,7 +70,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
import { defaultStore } from '@/store.js';
import { i18n } from '@/i18n.js';
import { $i } from '@/account.js';
-import { hostname } from '@/config.js';
+import { host as currentHost, hostname } from '@/config.js';
const emit = defineEmits<{
(ev: 'ok', selected: Misskey.entities.UserDetailed): void;
@@ -76,6 +80,7 @@ const emit = defineEmits<{
const props = defineProps<{
includeSelf?: boolean;
+ localOnly?: boolean;
}>();
const username = ref('');
@@ -92,7 +97,7 @@ function search() {
}
misskeyApi('users/search-by-username-and-host', {
username: username.value,
- host: host.value,
+ host: props.localOnly ? '.' : host.value,
limit: 10,
detail: false,
}).then(_users => {
@@ -125,11 +130,18 @@ function cancel() {
onMounted(() => {
misskeyApi('users/show', {
userIds: defaultStore.state.recentlyUsedUsers,
- }).then(users => {
- if (props.includeSelf && users.find(x => $i ? x.id === $i.id : true) == null) {
- recentUsers.value = [$i!, ...users];
+ }).then(foundUsers => {
+ const _users = foundUsers.filter((u) => {
+ if (props.localOnly) {
+ return u.host == null;
+ } else {
+ return true;
+ }
+ });
+ if (props.includeSelf && _users.find(x => $i ? x.id === $i.id : true) == null) {
+ recentUsers.value = [$i!, ..._users];
} else {
- recentUsers.value = users;
+ recentUsers.value = _users;
}
});
});
@@ -138,7 +150,7 @@ onMounted(() => {
<style lang="scss" module>
.form {
- padding: 0 var(--root-margin);
+ padding: calc(var(--root-margin) / 2) var(--root-margin);
}
.result,
diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts
index b01e8a54f7..b4b4bb4d39 100644
--- a/packages/frontend/src/os.ts
+++ b/packages/frontend/src/os.ts
@@ -419,10 +419,11 @@ export function form(title, form) {
});
}
-export async function selectUser(opts: { includeSelf?: boolean } = {}): Promise<Misskey.entities.UserDetailed> {
+export async function selectUser(opts: { includeSelf?: boolean; localOnly?: boolean; } = {}): Promise<Misskey.entities.UserDetailed> {
return new Promise((resolve, reject) => {
popup(defineAsyncComponent(() => import('@/components/MkUserSelectDialog.vue')), {
includeSelf: opts.includeSelf,
+ localOnly: opts.localOnly,
}, {
ok: user => {
resolve(user);
diff --git a/packages/frontend/src/pages/reversi/game.board.vue b/packages/frontend/src/pages/reversi/game.board.vue
index 8b59df06f7..eb4dbfdee0 100644
--- a/packages/frontend/src/pages/reversi/game.board.vue
+++ b/packages/frontend/src/pages/reversi/game.board.vue
@@ -37,11 +37,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.board">
<div :class="$style.boardInner">
<div v-if="showBoardLabels" :class="$style.labelsX">
- <span v-for="i in game.map[0].length" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
+ <span v-for="i in game.map[0].length" :key="i" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
</div>
<div style="display: flex;">
<div v-if="showBoardLabels" :class="$style.labelsY">
- <div v-for="i in game.map.length" :class="$style.labelsYLabel">{{ i }}</div>
+ <div v-for="i in game.map.length" :key="i" :class="$style.labelsYLabel">{{ i }}</div>
</div>
<div :class="$style.boardCells" :style="cellsStyle">
<div
@@ -66,8 +66,8 @@ SPDX-License-Identifier: AGPL-3.0-only
mode="default"
>
<template v-if="useAvatarAsStone">
- <img v-if="stone === true" :class="$style.boardCellStone" :src="blackUser.avatarUrl"/>
- <img v-else-if="stone === false" :class="$style.boardCellStone" :src="whiteUser.avatarUrl"/>
+ <img v-if="stone === true" :class="$style.boardCellStone" :src="blackUser.avatarUrl ?? undefined"/>
+ <img v-else-if="stone === false" :class="$style.boardCellStone" :src="whiteUser.avatarUrl ?? undefined"/>
</template>
<template v-else>
<img v-if="stone === true" :class="$style.boardCellStone" src="/client-assets/reversi/stone_b.png"/>
@@ -77,11 +77,11 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</div>
<div v-if="showBoardLabels" :class="$style.labelsY">
- <div v-for="i in game.map.length" :class="$style.labelsYLabel">{{ i }}</div>
+ <div v-for="i in game.map.length" :key="i" :class="$style.labelsYLabel">{{ i }}</div>
</div>
</div>
<div v-if="showBoardLabels" :class="$style.labelsX">
- <span v-for="i in game.map[0].length" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
+ <span v-for="i in game.map[0].length" :key="i" :class="$style.labelsXLabel">{{ String.fromCharCode(64 + i) }}</span>
</div>
</div>
</div>
@@ -162,13 +162,14 @@ const $i = signinRequired();
const props = defineProps<{
game: Misskey.entities.ReversiGameDetailed;
- connection?: Misskey.ChannelConnection | null;
+ connection?: Misskey.ChannelConnection<Misskey.Channels['reversiGame']> | null;
}>();
const showBoardLabels = ref<boolean>(false);
const useAvatarAsStone = ref<boolean>(true);
const autoplaying = ref<boolean>(false);
-const game = ref<Misskey.entities.ReversiGameDetailed>(deepClone(props.game));
+// eslint-disable-next-line vue/no-setup-props-destructure
+const game = ref<Misskey.entities.ReversiGameDetailed & { logs: Reversi.Serializer.SerializedLog[] }>(deepClone(props.game));
const logPos = ref<number>(game.value.logs.length);
const engine = shallowRef<Reversi.Game>(Reversi.Serializer.restoreGame({
map: game.value.map,
@@ -256,7 +257,7 @@ if (game.value.isStarted && !game.value.isEnded) {
const appliedOps: string[] = [];
-function putStone(pos) {
+function putStone(pos: number) {
if (game.value.isEnded) return;
if (!iAmPlayer.value) return;
if (!isMyTurn.value) return;
@@ -305,7 +306,7 @@ if (!props.game.isEnded) {
}, TIMER_INTERVAL_SEC * 1000, { immediate: false, afterMounted: true });
}
-async function onStreamLog(log: Reversi.Serializer.Log & { id: string | null }) {
+async function onStreamLog(log) {
game.value.logs = Reversi.Serializer.serializeLogs([
...Reversi.Serializer.deserializeLogs(game.value.logs),
log,
diff --git a/packages/frontend/src/pages/reversi/index.vue b/packages/frontend/src/pages/reversi/index.vue
index 8deaead698..431bb8c458 100644
--- a/packages/frontend/src/pages/reversi/index.vue
+++ b/packages/frontend/src/pages/reversi/index.vue
@@ -118,6 +118,7 @@ import MkPagination from '@/components/MkPagination.vue';
import { useRouter } from '@/global/router/supplier.js';
import * as os from '@/os.js';
import { useInterval } from '@/scripts/use-interval.js';
+import { pleaseLogin } from '@/scripts/please-login.js';
import * as sound from '@/scripts/sound.js';
const myGamesPagination = {
@@ -193,7 +194,9 @@ async function matchHeatbeat() {
}
async function matchUser() {
- const user = await os.selectUser({ local: true });
+ pleaseLogin();
+
+ const user = await os.selectUser({ localOnly: true });
if (user == null) return;
matchingUser.value = user;
@@ -202,6 +205,8 @@ async function matchUser() {
}
function matchAny(ev: MouseEvent) {
+ pleaseLogin();
+
os.popupMenu([{
text: i18n.ts._reversi.allowIrregularRules,
action: () => {