summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2024-07-19 12:19:00 +0000
committerdakkar <dakkar@thenautilus.net>2024-07-19 12:19:00 +0000
commit3d5fd4a12df34e7fbed2fe46d5210f37b4bf17d7 (patch)
tree4177a8a6459c96fff7c20ee9a07b9442d8b89602
parentmerge: feat: Filter notifications by edit (!573) (diff)
parentFix vertical align of ... (diff)
downloadsharkey-3d5fd4a12df34e7fbed2fe46d5210f37b4bf17d7.tar.gz
sharkey-3d5fd4a12df34e7fbed2fe46d5210f37b4bf17d7.tar.bz2
sharkey-3d5fd4a12df34e7fbed2fe46d5210f37b4bf17d7.zip
merge: Drive searching by alt text and title (!564)
View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/564 Approved-by: dakkar <dakkar@thenautilus.net> Approved-by: Marie <marie@kaifa.ch>
-rw-r--r--locales/en-US.yml1
-rw-r--r--locales/index.d.ts4
-rw-r--r--locales/ja-JP.yml1
-rw-r--r--packages/backend/src/server/api/endpoints/drive/files.ts6
-rw-r--r--packages/backend/src/server/api/endpoints/drive/folders.ts5
-rw-r--r--packages/frontend/src/components/MkDrive.vue23
6 files changed, 38 insertions, 2 deletions
diff --git a/locales/en-US.yml b/locales/en-US.yml
index 598f742896..03a5a91e84 100644
--- a/locales/en-US.yml
+++ b/locales/en-US.yml
@@ -321,6 +321,7 @@ lightThemes: "Light themes"
darkThemes: "Dark themes"
syncDeviceDarkMode: "Sync Dark Mode with your device settings"
drive: "Drive"
+driveSearchbarPlaceholder: "Search drive"
fileName: "Filename"
selectFile: "Select a file"
selectFiles: "Select files"
diff --git a/locales/index.d.ts b/locales/index.d.ts
index e3434d7dbf..7020bc2159 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -1301,6 +1301,10 @@ export interface Locale extends ILocale {
*/
"drive": string;
/**
+ * 検索ドライブ
+ */
+ "driveSearchbarPlaceholder": string;
+ /**
* ファイル名
*/
"fileName": string;
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index c25b421172..8f3bb4f48c 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -321,6 +321,7 @@ lightThemes: "明るいテーマ"
darkThemes: "暗いテーマ"
syncDeviceDarkMode: "デバイスのダークモードと同期する"
drive: "ドライブ"
+driveSearchbarPlaceholder: "検索ドライブ"
fileName: "ファイル名"
selectFile: "ファイルを選択"
selectFiles: "ファイルを選択"
diff --git a/packages/backend/src/server/api/endpoints/drive/files.ts b/packages/backend/src/server/api/endpoints/drive/files.ts
index 10c521332d..6d87d5ddf7 100644
--- a/packages/backend/src/server/api/endpoints/drive/files.ts
+++ b/packages/backend/src/server/api/endpoints/drive/files.ts
@@ -9,6 +9,7 @@ import type { DriveFilesRepository } from '@/models/_.js';
import { QueryService } from '@/core/QueryService.js';
import { DriveFileEntityService } from '@/core/entities/DriveFileEntityService.js';
import { DI } from '@/di-symbols.js';
+import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['drive'],
@@ -37,6 +38,7 @@ export const paramDef = {
folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
type: { type: 'string', nullable: true, pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1) },
sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size', null] },
+ searchQuery: { type: 'string', default: '' }
},
required: [],
} as const;
@@ -60,6 +62,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
query.andWhere('file.folderId IS NULL');
}
+ if (ps.searchQuery.length > 0) {
+ query.andWhere('file.name ILIKE :searchQuery OR file.comment ILIKE :searchQuery', { searchQuery: `%${sqlLikeEscape(ps.searchQuery)}%` });
+ }
+
if (ps.type) {
if (ps.type.endsWith('/*')) {
query.andWhere('file.type like :type', { type: ps.type.replace('/*', '/') + '%' });
diff --git a/packages/backend/src/server/api/endpoints/drive/folders.ts b/packages/backend/src/server/api/endpoints/drive/folders.ts
index 8c4848f8e1..9bcd824882 100644
--- a/packages/backend/src/server/api/endpoints/drive/folders.ts
+++ b/packages/backend/src/server/api/endpoints/drive/folders.ts
@@ -9,6 +9,7 @@ import type { DriveFoldersRepository } from '@/models/_.js';
import { QueryService } from '@/core/QueryService.js';
import { DriveFolderEntityService } from '@/core/entities/DriveFolderEntityService.js';
import { DI } from '@/di-symbols.js';
+import { sqlLikeEscape } from '@/misc/sql-like-escape.js';
export const meta = {
tags: ['drive'],
@@ -35,6 +36,7 @@ export const paramDef = {
sinceId: { type: 'string', format: 'misskey:id' },
untilId: { type: 'string', format: 'misskey:id' },
folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
+ searchQuery: { type: 'string', default: '' }
},
required: [],
} as const;
@@ -58,6 +60,9 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
query.andWhere('folder.parentId IS NULL');
}
+ if (ps.searchQuery.length > 0) {
+ query.andWhere('folder.name ILIKE :searchQuery', { searchQuery: `%${sqlLikeEscape(ps.searchQuery)}%` });
+ }
const folders = await query.limit(ps.limit).getMany();
return await Promise.all(folders.map(folder => this.driveFolderEntityService.pack(folder)));
diff --git a/packages/frontend/src/components/MkDrive.vue b/packages/frontend/src/components/MkDrive.vue
index a9717b4fb7..222fabb8f4 100644
--- a/packages/frontend/src/components/MkDrive.vue
+++ b/packages/frontend/src/components/MkDrive.vue
@@ -30,7 +30,14 @@ SPDX-License-Identifier: AGPL-3.0-only
<span v-if="folder != null" :class="[$style.navPathItem, $style.navSeparator]"><i class="ti ti-chevron-right"></i></span>
<span v-if="folder != null" :class="[$style.navPathItem, $style.navCurrent]">{{ folder.name }}</span>
</div>
- <button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
+ <div :class="$style.navMenu">
+ <!-- "Search drive via alt text or file names" -->
+ <MkInput v-model="searchQuery" :large="true" :autofocus="true" type="search" :placeholder="i18n.ts.driveSearchbarPlaceholder" @enter="fetch">
+ <template #prefix><i class="ph-magnifying-glass ph-bold ph-lg"></i></template>
+ </MkInput>
+
+ <button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
+ </div>
</nav>
<div
ref="main"
@@ -102,6 +109,7 @@ import type { MenuItem } from '@/types/menu.js';
import XNavFolder from '@/components/MkDrive.navFolder.vue';
import XFolder from '@/components/MkDrive.folder.vue';
import XFile from '@/components/MkDrive.file.vue';
+import MkInput from '@/components/MkInput.vue';
import * as os from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { useStream } from '@/stream.js';
@@ -110,6 +118,8 @@ import { i18n } from '@/i18n.js';
import { uploadFile, uploads } from '@/scripts/upload.js';
import { claimAchievement } from '@/scripts/achievements.js';
+const searchQuery = ref('');
+
const props = withDefaults(defineProps<{
initialFolder?: Misskey.entities.DriveFolder;
type?: string;
@@ -540,6 +550,7 @@ async function fetch() {
const foldersPromise = misskeyApi('drive/folders', {
folderId: folder.value ? folder.value.id : null,
limit: foldersMax + 1,
+ searchQuery: searchQuery.value.toString().trim(),
}).then(fetchedFolders => {
if (fetchedFolders.length === foldersMax + 1) {
moreFolders.value = true;
@@ -552,6 +563,7 @@ async function fetch() {
folderId: folder.value ? folder.value.id : null,
type: props.type,
limit: filesMax + 1,
+ searchQuery: searchQuery.value.toString().trim(),
}).then(fetchedFiles => {
if (fetchedFiles.length === filesMax + 1) {
moreFiles.value = true;
@@ -578,6 +590,7 @@ function fetchMoreFolders() {
type: props.type,
untilId: folders.value.at(-1)?.id,
limit: max + 1,
+ searchQuery: searchQuery.value.toString().trim(),
}).then(folders => {
if (folders.length === max + 1) {
moreFolders.value = true;
@@ -601,6 +614,7 @@ function fetchMoreFiles() {
type: props.type,
untilId: files.value.at(-1)?.id,
limit: max + 1,
+ searchQuery: searchQuery.value.toString().trim(),
}).then(files => {
if (files.length === max + 1) {
moreFiles.value = true;
@@ -747,8 +761,13 @@ onBeforeUnmount(() => {
}
.navMenu {
+ display: flex;
margin-left: auto;
- padding: 0 12px;
+ align-items: center;
+}
+
+.navMenu > *:not(:last-child) {
+ padding-right: 12px;
}
.main {