mirror of
https://github.com/lanyeeee/bilibili-video-downloader.git
synced 2026-09-04 23:17:45 +08:00
refactor: 抽象出IconButton以优化代码
This commit is contained in:
Vendored
+1
@@ -10,6 +10,7 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
ColorfulTag: typeof import('./src/components/ColorfulTag.vue')['default']
|
||||
FloatLabelInput: typeof import('./src/components/FloatLabelInput.vue')['default']
|
||||
IconButton: typeof import('./src/components/IconButton.vue')['default']
|
||||
NA: typeof import('naive-ui')['NA']
|
||||
NBadge: typeof import('naive-ui')['NBadge']
|
||||
NButton: typeof import('naive-ui')['NButton']
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
href?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
v-if="href !== undefined"
|
||||
:href="href"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6 active:text-white">
|
||||
<slot />
|
||||
</a>
|
||||
<div
|
||||
v-else
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6 active:text-white">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
@@ -5,6 +5,7 @@ import { ensureHttps, isElementInViewport, playTaskToQueueAnimation } from '../.
|
||||
import { PhDownloadSimple, PhGoogleChromeLogo, PhMagnifyingGlass } from '@phosphor-icons/vue'
|
||||
import { EpInBangumiFollow } from '../../../bindings.ts'
|
||||
import SimpleCheckbox from '../../../components/SimpleCheckbox.vue'
|
||||
import IconButton from '../../../components/IconButton.vue'
|
||||
|
||||
const searchPaneRef = inject(searchPaneRefKey)
|
||||
|
||||
@@ -18,7 +19,7 @@ const props = defineProps<{
|
||||
|
||||
const navDownloadButtonRef = inject(navDownloadButtonRefKey)
|
||||
const rootDivRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<InstanceType<typeof IconButton>>()
|
||||
|
||||
async function handleDownloadClick() {
|
||||
if (props.downloadEpisode === undefined) {
|
||||
@@ -34,7 +35,7 @@ function playDownloadAnimation() {
|
||||
return
|
||||
}
|
||||
|
||||
const from = downloadButtonRef.value
|
||||
const from = downloadButtonRef.value?.$el
|
||||
const to = navDownloadButtonRef?.value
|
||||
|
||||
if (from instanceof Element && to !== undefined) {
|
||||
@@ -71,29 +72,20 @@ defineExpose({ playDownloadAnimation, ep: props.ep })
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1 items-center mt-2">
|
||||
<a
|
||||
:href="`https://www.bilibili.com/bangumi/play/ss${ep.season_id}`"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
title="在浏览器中打开"
|
||||
class="p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6">
|
||||
<IconButton title="在浏览器中打开" :href="`https://www.bilibili.com/bangumi/play/ss${ep.season_id}`">
|
||||
<PhGoogleChromeLogo :size="24" />
|
||||
</a>
|
||||
<div
|
||||
title="在下载器内搜索"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="searchPaneRef?.search(`ss${props.ep.season_id}`, 'Bangumi')">
|
||||
</IconButton>
|
||||
<IconButton title="在下载器内搜索" @click="searchPaneRef?.search(`ss${props.ep.season_id}`, 'Bangumi')">
|
||||
<PhMagnifyingGlass :size="24" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="downloadEpisode !== undefined"
|
||||
ref="downloadButtonRef"
|
||||
class="ml-auto"
|
||||
title="一键下载"
|
||||
class="ml-auto cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="handleDownloadClick">
|
||||
<PhDownloadSimple :size="24" />
|
||||
</div>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -19,6 +19,7 @@ import ColorfulTag from '../../../components/ColorfulTag.vue'
|
||||
import { searchPaneRefKey } from '../../../injection_keys.ts'
|
||||
import { ProgressData } from '../DownloadPane.vue'
|
||||
import { ensureHttps } from '../../../utils.tsx'
|
||||
import IconButton from '../../../components/IconButton.vue'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
@@ -206,34 +207,24 @@ function handleSearchClick() {
|
||||
</div>
|
||||
|
||||
<div class="ml-auto flex gap-2 items-center">
|
||||
<div
|
||||
<IconButton
|
||||
v-if="p.state === 'Completed' && p.video_task.selected"
|
||||
title="打开mp4目录"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="showMp4InFileManager(p.episode_dir, p.filename)">
|
||||
<PhFileVideo :size="24" />
|
||||
</div>
|
||||
<div
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="p.state === 'Completed'"
|
||||
title="打开下载目录"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="showEpisodeDirInFileManager(p.episode_dir)">
|
||||
<PhFolderOpen :size="24" />
|
||||
</div>
|
||||
<div
|
||||
title="在下载器内搜索"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="handleSearchClick">
|
||||
</IconButton>
|
||||
<IconButton title="在下载器内搜索" @click="handleSearchClick">
|
||||
<PhMagnifyingGlass :size="24" />
|
||||
</div>
|
||||
<a
|
||||
:href="href"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
title="在浏览器中打开"
|
||||
class="p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6">
|
||||
</IconButton>
|
||||
<IconButton title="在浏览器中打开" :href="href">
|
||||
<PhGoogleChromeLogo :size="24" />
|
||||
</a>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ensureHttps, isElementInViewport, playTaskToQueueAnimation } from '../.
|
||||
import { computed, inject, ref } from 'vue'
|
||||
import { navDownloadButtonRefKey } from '../../../injection_keys.ts'
|
||||
import { SearchType } from '../../SearchPane/SearchPane.vue'
|
||||
import IconButton from '../../../components/IconButton.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
media: MediaInFav
|
||||
@@ -18,7 +19,7 @@ const props = defineProps<{
|
||||
|
||||
const navDownloadButtonRef = inject(navDownloadButtonRefKey)
|
||||
const rootDivRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<InstanceType<typeof IconButton>>()
|
||||
|
||||
const openInBrowserHref = computed<string | undefined>(() => {
|
||||
if (props.media.type === 2) {
|
||||
@@ -54,7 +55,7 @@ function playDownloadAnimation() {
|
||||
return
|
||||
}
|
||||
|
||||
const from = downloadButtonRef.value
|
||||
const from = downloadButtonRef.value?.$el
|
||||
const to = navDownloadButtonRef?.value
|
||||
|
||||
if (from instanceof Element && to !== undefined) {
|
||||
@@ -121,31 +122,20 @@ defineExpose({ playDownloadAnimation, media: props.media })
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1 items-center">
|
||||
<a
|
||||
:href="openInBrowserHref"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
title="在浏览器中打开"
|
||||
class="p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6">
|
||||
<IconButton title="在浏览器中打开" :href="openInBrowserHref">
|
||||
<PhGoogleChromeLogo :size="24" />
|
||||
</a>
|
||||
|
||||
<div
|
||||
v-if="search !== undefined"
|
||||
title="在下载器内搜索"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="searchInSearchPane">
|
||||
</IconButton>
|
||||
<IconButton v-if="search !== undefined" title="在下载器内搜索" @click="searchInSearchPane">
|
||||
<PhMagnifyingGlass :size="24" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="props.downloadEpisode !== undefined"
|
||||
ref="downloadButtonRef"
|
||||
class="ml-auto"
|
||||
title="一键下载"
|
||||
class="ml-auto cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="handleDownloadClick">
|
||||
<PhDownloadSimple :size="24" />
|
||||
</div>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { navDownloadButtonRefKey } from '../../../injection_keys.ts'
|
||||
import { ensureHttps, isElementInViewport, playTaskToQueueAnimation } from '../../../utils.tsx'
|
||||
import { PhDownloadSimple, PhGoogleChromeLogo, PhMagnifyingGlass } from '@phosphor-icons/vue'
|
||||
import SimpleCheckbox from '../../../components/SimpleCheckbox.vue'
|
||||
import IconButton from '../../../components/IconButton.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
episodeType: EpisodeType
|
||||
@@ -19,7 +20,7 @@ const props = defineProps<{
|
||||
|
||||
const navDownloadButtonRef = inject(navDownloadButtonRefKey)
|
||||
const rootDivRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<InstanceType<typeof IconButton>>()
|
||||
|
||||
const openInBrowserHref = computed<string | undefined>(() => {
|
||||
if (props.episodeType === 'Normal') {
|
||||
@@ -98,7 +99,7 @@ function playDownloadAnimation() {
|
||||
return
|
||||
}
|
||||
|
||||
const from = downloadButtonRef.value
|
||||
const from = downloadButtonRef.value?.$el
|
||||
const to = navDownloadButtonRef?.value
|
||||
|
||||
if (from instanceof Element && to !== undefined) {
|
||||
@@ -175,31 +176,20 @@ defineExpose({ playDownloadAnimation, historyDetail: props.historyDetail })
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1 items-center">
|
||||
<a
|
||||
:href="openInBrowserHref"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
title="在浏览器中打开"
|
||||
class="p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6">
|
||||
<IconButton title="在浏览器中打开" :href="openInBrowserHref">
|
||||
<PhGoogleChromeLogo :size="24" />
|
||||
</a>
|
||||
|
||||
<div
|
||||
v-if="search !== undefined"
|
||||
title="在下载器内搜索"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="searchInSearchPane">
|
||||
</IconButton>
|
||||
<IconButton v-if="search !== undefined" title="在下载器内搜索" @click="searchInSearchPane">
|
||||
<PhMagnifyingGlass :size="24" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="props.downloadEpisode !== undefined"
|
||||
ref="downloadButtonRef"
|
||||
class="ml-auto"
|
||||
title="一键下载"
|
||||
class="ml-auto cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="handleDownloadClick">
|
||||
<PhDownloadSimple :size="24" />
|
||||
</div>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -18,6 +18,7 @@ import PartsDialogContent from './PartsDialogContent.vue'
|
||||
import { ensureHttps, extractBvid, isElementInViewport, playTaskToQueueAnimation } from '../../../utils.tsx'
|
||||
import { navDownloadButtonRefKey } from '../../../injection_keys.ts'
|
||||
import { SearchType } from '../SearchPane.vue'
|
||||
import IconButton from '../../../components/IconButton.vue'
|
||||
|
||||
onMounted(() => console.log('EpisodeCard mounted'))
|
||||
onUpdated(() => console.log('EpisodeCard updated'))
|
||||
@@ -51,7 +52,7 @@ const props = defineProps<{
|
||||
|
||||
const navDownloadButtonRef = inject(navDownloadButtonRefKey)
|
||||
const rootDivRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<InstanceType<typeof IconButton>>()
|
||||
|
||||
const episodeInfo = computed<EpisodeInfo>(() => {
|
||||
if (props.episodeType === 'NormalSingle') {
|
||||
@@ -174,7 +175,7 @@ function playDownloadAnimation() {
|
||||
return
|
||||
}
|
||||
|
||||
const from = downloadButtonRef.value
|
||||
const from = downloadButtonRef.value?.$el
|
||||
const to = navDownloadButtonRef?.value
|
||||
|
||||
if (from instanceof Element && to !== undefined) {
|
||||
@@ -226,38 +227,26 @@ defineExpose({ playDownloadAnimation, episodeInfo })
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1 items-center">
|
||||
<a
|
||||
v-if="episodeInfo.href !== undefined"
|
||||
:href="episodeInfo.href"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
title="在浏览器中打开"
|
||||
class="p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6">
|
||||
<IconButton v-if="episodeInfo.href !== undefined" title="在浏览器中打开" :href="episodeInfo.href">
|
||||
<PhGoogleChromeLogo :size="24" />
|
||||
</a>
|
||||
<div
|
||||
v-if="partsButtonShowing"
|
||||
title="查看分P"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="handlePartsButtonClick">
|
||||
</IconButton>
|
||||
<IconButton v-if="partsButtonShowing" title="查看分P" @click="handlePartsButtonClick">
|
||||
<PhQueue :size="24" />
|
||||
</div>
|
||||
<div
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="search !== undefined && episodeInfo.bvid !== undefined"
|
||||
title="在下载器内搜索"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="search(episodeInfo.bvid, 'Normal')">
|
||||
<PhMagnifyingGlass :size="24" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref="downloadButtonRef"
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="downloadEpisode !== undefined"
|
||||
ref="downloadButtonRef"
|
||||
title="一键下载"
|
||||
class="ml-auto cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
class="ml-auto"
|
||||
@click="handleDownloadClick">
|
||||
<PhDownloadSimple :size="24" />
|
||||
</div>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ensureHttps, extractEpId, isElementInViewport, playTaskToQueueAnimation
|
||||
import { PhDownloadSimple, PhGoogleChromeLogo, PhMagnifyingGlass } from '@phosphor-icons/vue'
|
||||
import SimpleCheckbox from '../../../components/SimpleCheckbox.vue'
|
||||
import { SearchType } from '../../SearchPane/SearchPane.vue'
|
||||
import IconButton from '../../../components/IconButton.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
media: MediaInWatchLater
|
||||
@@ -18,7 +19,7 @@ const props = defineProps<{
|
||||
|
||||
const navDownloadButtonRef = inject(navDownloadButtonRefKey)
|
||||
const rootDivRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<HTMLDivElement>()
|
||||
const downloadButtonRef = ref<InstanceType<typeof IconButton>>()
|
||||
|
||||
const openInBrowserHref = computed<string>(() => {
|
||||
if (props.media.redirect_url === null) {
|
||||
@@ -43,7 +44,7 @@ function playDownloadAnimation() {
|
||||
return
|
||||
}
|
||||
|
||||
const from = downloadButtonRef.value
|
||||
const from = downloadButtonRef.value?.$el
|
||||
const to = navDownloadButtonRef?.value
|
||||
|
||||
if (from instanceof Element && to !== undefined) {
|
||||
@@ -109,31 +110,20 @@ defineExpose({ playDownloadAnimation, media: props.media })
|
||||
</div>
|
||||
|
||||
<div class="flex gap-1 items-center">
|
||||
<a
|
||||
:href="openInBrowserHref"
|
||||
target="_blank"
|
||||
draggable="false"
|
||||
title="在浏览器中打开"
|
||||
class="p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6">
|
||||
<IconButton title="在浏览器中打开" :href="openInBrowserHref">
|
||||
<PhGoogleChromeLogo :size="24" />
|
||||
</a>
|
||||
|
||||
<div
|
||||
v-if="search !== undefined"
|
||||
title="在下载器内搜索"
|
||||
class="cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
@click="searchInSearchPane">
|
||||
</IconButton>
|
||||
<IconButton v-if="search !== undefined" title="在下载器内搜索" @click="searchInSearchPane">
|
||||
<PhMagnifyingGlass :size="24" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
</IconButton>
|
||||
<IconButton
|
||||
v-if="downloadEpisode !== undefined"
|
||||
ref="downloadButtonRef"
|
||||
title="一键下载"
|
||||
class="ml-auto cursor-pointer p-1 rounded-lg flex items-center justify-between text-gray-6 hover:bg-sky-5 hover:text-white active:bg-sky-6"
|
||||
class="ml-auto"
|
||||
@click="handleDownloadClick">
|
||||
<PhDownloadSimple :size="24" />
|
||||
</div>
|
||||
</IconButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user