Skip to content

Commit

Permalink
feat: 검색 위젯 (1673beta#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
noridev committed Oct 2, 2024
1 parent ecf631e commit d7da3e6
Show file tree
Hide file tree
Showing 8 changed files with 175 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_CHERRYPICK.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
- Feat: 노트 동작 버튼을 개인화할 수 있음 (kokonect-link/cherrypick#501)
- Feat: 답글 대상 노트의 반투명 옵션을 선택할 수 있음 (kokonect-link/cherrypick#495)
- Feat: 사용자 페이지의 미디어 탭을 그리드 레이아웃으로 설정할 수 있음 (kokonect-link/cherrypick#494)
- Feat: 검색 위젯 (1673beta/cherrypick#125)

### Client
- Enhance: CherryPick 업데이트 페이지를 제어판 목록에 추가함
Expand Down
1 change: 1 addition & 0 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2490,6 +2490,7 @@ _widgets:
chooseList: "Select a list"
clicker: "Clicker"
birthdayFollowings: "Users who celebrate their birthday today"
search: "Search"
_cw:
hide: "Hide"
show: "Show content"
Expand Down
4 changes: 4 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9781,6 +9781,10 @@ export interface Locale extends ILocale {
* 今日誕生日のユーザー
*/
"birthdayFollowings": string;
/**
* 検索
*/
"search": string;
};
"_cw": {
/**
Expand Down
1 change: 1 addition & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2569,6 +2569,7 @@ _widgets:
chooseList: "リストを選択"
clicker: "クリッカー"
birthdayFollowings: "今日誕生日のユーザー"
search: "検索"

_cw:
hide: "隠す"
Expand Down
1 change: 1 addition & 0 deletions locales/ko-KR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2513,6 +2513,7 @@ _widgets:
chooseList: "리스트 선택"
clicker: "클리커"
birthdayFollowings: "오늘 생일인 사용자"
search: "검색"
_cw:
hide: "가리기"
show: "더 보기"
Expand Down
30 changes: 30 additions & 0 deletions packages/frontend/src/components/MkSearchResultWindow.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!--
SPDX-FileCopyrightText: marie and other Sharkey contributors, and esurio
SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<MkWindow ref="window" :initialWidth="600" :initialHeight="450" :canResize="true" @closed="emit('closed')">
<template #header>
<i class="ti ti-zoom" style="margin-right: 0.5em;"></i>
<b>{{ i18n.ts.searchResult }}</b>
</template>
<MkNotes :key="props.noteKey" :pagination="props.notePagination"/>
</MkWindow>
</template>

<script lang="ts" setup>
import { } from 'vue';
import type { Paging } from '@/components/MkPagination.vue';
import MkNotes from '@/components/MkNotes.vue';
import MkWindow from '@/components/MkWindow.vue';
import { i18n } from '@/i18n.js';
const props = defineProps<{
noteKey: string | number | symbol | undefined;
notePagination: Paging;
}>();
const emit = defineEmits<{
(ev: 'closed'): void;
}>();
</script>
135 changes: 135 additions & 0 deletions packages/frontend/src/widgets/WidgetSearch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<!--
SPDX-FileCopyrightText: marie and other Sharkey contributors, and esurio
SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<MkContainer :showHeader="widgetProps.showHeader" :class="$style.skwSearch">
<MkInput v-model="searchQuery" :large="true" type="search" @keydown="onInputKeydown">
<template #suffix>
<button :class="$style.searchBtn" @click="search"><i class="ti ti-zoom"></i></button>
</template>
</MkInput>
</MkContainer>
</template>

<script lang="ts" setup>
import { defineAsyncComponent, ref } from 'vue';
import { useWidgetPropsManager, WidgetComponentEmits, WidgetComponentExpose, WidgetComponentProps } from './widget.js';
import MkInput from '@/components/MkInput.vue';
import MkContainer from '@/components/MkContainer.vue';
import { i18n } from '@/i18n.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import * as os from '@/os.js';
import { useRouter } from '@/router/supplier.js';
import { GetFormResultType } from '@/scripts/form.js';
const name = 'search';
const widgetPropsDef = {
showHeader: {
type: 'boolean' as const,
default: false,
},
};
type WidgetProps = GetFormResultType<typeof widgetPropsDef>;
const props = defineProps<WidgetComponentProps<WidgetProps>>();
const emit = defineEmits<WidgetComponentEmits<WidgetProps>>();
const { widgetProps, configure } = useWidgetPropsManager(name,
widgetPropsDef,
props,
emit,
);
function onInputKeydown(evt: KeyboardEvent) {
if (evt.key === 'Enter') {
evt.preventDefault();
evt.stopPropagation();
search();
}
}
const router = useRouter();
let key = ref(0);
let searchQuery = ref('');
let notePagination = ref();
let isLocalOnly = ref(false);
async function search() {
const query = searchQuery.value.toString().trim();
if (query == null || query === '') return;
if (query.startsWith('https://')) {
const promise = misskeyApi('ap/show', {
uri: query,
});
os.promiseDialog(promise, null, null, i18n.ts.fetchingAsApObject);
const res = await promise;
if (res.type === 'User') {
router.push(`/@${res.object.username}@${res.object.host}`);
} else if (res.type === 'Note') {
router.push(`/notes/${res.object.id}`);
}
return;
}
if (query.match(/^@[a-z0-9_.-]+@[a-z0-9_.-]+$/i)) {
router.push(`/${query}`);
return;
}
if (query.startsWith('#')) {
router.push(`/tags/${encodeURIComponent(query.substring(1))}`);
return;
}
notePagination.value = {
endpoint: 'notes/search',
limit: 10,
params: {
query: searchQuery,
userId: null,
},
};
if (isLocalOnly.value) notePagination.value.params.host = '.';
key.value++;
const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkSearchResultWindow.vue')), {
noteKey: key.value,
notePagination: notePagination.value,
}, {
closed: () => dispose(),
});
}
defineExpose<WidgetComponentExpose>({
name,
configure,
id: props.widget ? props.widget.id : null,
});
</script>

<style lang="scss" module>
.skwSearch {
border-radius: var(--radius-sm) !important;
}
.searchBtn {
position: relative;
z-index: 2;
margin: 0 auto;
border: none;
background: none;
pointer-events: auto;
}
</style>
2 changes: 2 additions & 0 deletions packages/frontend/src/widgets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export default function(app: App) {
app.component('WidgetUserList', defineAsyncComponent(() => import('./WidgetUserList.vue')));
app.component('WidgetClicker', defineAsyncComponent(() => import('./WidgetClicker.vue')));
app.component('WidgetBirthdayFollowings', defineAsyncComponent(() => import('./WidgetBirthdayFollowings.vue')));
app.component('WidgetSearch', defineAsyncComponent(() => import('./WidgetSearch.vue')));
}

export const widgets = [
Expand Down Expand Up @@ -65,4 +66,5 @@ export const widgets = [
'userList',
'clicker',
'birthdayFollowings',
'search',
];

0 comments on commit d7da3e6

Please sign in to comment.