Skip to content

Commit

Permalink
release: v1.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ltaoo committed Aug 27, 2023
1 parent 249d40e commit 0a13718
Show file tree
Hide file tree
Showing 9 changed files with 306 additions and 50 deletions.
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="zh-CN">

<head>
<meta charset="utf-8" />
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@family-flix/admin",
"private": true,
"version": "1.8.0",
"version": "1.9.0",
"scripts": {
"dev": "vite --port 3003 --host",
"build": "tsc && vite build",
Expand Down
39 changes: 24 additions & 15 deletions src/domains/drive/files.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
/**
* @todo 如果删除当前选中的文件夹,子文件夹在视图上也要同步移除
*/
import { Handler } from "mitt";

import { BaseDomain } from "@/domains/base";
import { ListCore } from "@/domains/list";
import { RequestCore } from "@/domains/request";
import { FileType } from "@/constants";
import { ScrollViewCore } from "@/domains/ui";
import { FileType } from "@/constants";

import { fetchDriveFiles, deleteFileOfDrive, renameFileOfDrive } from "./services";
import { AliyunFilePath, AliyunDriveFile } from "./types";
import { Result } from "@/types";

type FileColumn = {
list: ListCore<typeof fetchDriveFiles, AliyunDriveFile>;
Expand Down Expand Up @@ -205,29 +207,36 @@ export class AliyunDriveFilesCore extends BaseDomain<TheTypesOfEvents> {
position: [number, number];
onLoading?: (loading: boolean) => void;
onFailed?: (error: Error) => void;
onSuccess?: (data: { job_id: string; deleteFile: () => void }) => void;
onSuccess?: (options: { job_id?: string; deleteFile: () => void }) => void;
}) {
const { file, position, onLoading, onFailed, onSuccess } = options;
const [columnIndex, fileIndex] = position;
const folderColumns = this.folderColumns;
function delete_file() {
const column = folderColumns[columnIndex];
column.list.deleteItem((f) => {
if (f.file_id === file.file_id) {
return true;
}
return false;
});
}
const folderDeletingRequest = new RequestCore(deleteFileOfDrive, {
onLoading,
onFailed,
onSuccess: (data) => {
if (onSuccess) {
onSuccess({
job_id: data.job_id,
// @todo 这个实现很糟糕
deleteFile: () => {
const column = folderColumns[columnIndex];
column.list.deleteItem((f) => {
if (f.file_id === file.file_id) {
return true;
onSuccess(
data
? // @todo 这个实现很糟糕
{
job_id: data.job_id,
deleteFile: delete_file,
}
: {
deleteFile: delete_file,
}
return false;
});
},
});
);
}
},
});
Expand Down
63 changes: 53 additions & 10 deletions src/pages/drive/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { SelectionCore } from "@/domains/cur";
import { ViewComponent } from "@/types";
import { FileType } from "@/constants";
import { createJob, homeLayout } from "@/store";
import { RequestCore } from "@/domains/request";
import { sync_folder } from "@/services";

export const DriveProfilePage: ViewComponent = (props) => {
const { app, view } = props;
Expand Down Expand Up @@ -99,20 +101,18 @@ export const DriveProfilePage: ViewComponent = (props) => {
text: ["删除文件失败", error.message],
});
},
onSuccess(data) {
onSuccess(opt) {
app.tip({
text: ["开始删除,需要等待一会"],
text: ["删除成功"],
});
opt.deleteFile();
folderDeletingConfirmDialog.hide();
fileSelect.clear();
if (!opt.job_id) {
return;
}
createJob({
job_id: data.job_id,
onFinish() {
app.tip({
text: ["完成删除"],
});
data.deleteFile();
},
job_id: opt.job_id,
});
},
});
Expand Down Expand Up @@ -179,6 +179,11 @@ export const DriveProfilePage: ViewComponent = (props) => {
fileMenu.hide();
},
});
const syncFolderRequest = new RequestCore(sync_folder, {
// onLoading(loading) {
// folderSyncItem.disable();
// },
});
const folderDeletingItem = new MenuItemCore({
label: "删除",
async onClick() {
Expand All @@ -190,14 +195,51 @@ export const DriveProfilePage: ViewComponent = (props) => {
}
const [file] = driveFileManage.virtualSelectedFolder;
fileSelect.select(driveFileManage.virtualSelectedFolder);
folderDeletingConfirmDialog.setTitle(`确认删除 '${file.name}' 吗?`);
folderDeletingConfirmDialog.setTitle(`删除文件`);
folderDeletingConfirmDialog.show();
fileMenu.hide();
},
});
const linkSharedFileItem = new MenuItemCore({
label: "关联分享资源",
});
const folderSyncItem = new MenuItemCore({
label: "同步资源",
async onClick() {
if (!driveFileManage.virtualSelectedFolder) {
app.tip({
text: ["请选择要同步的文件夹"],
});
return;
}
const [file] = driveFileManage.virtualSelectedFolder;
if (file.type === FileType.File) {
app.tip({
text: ["请选择文件夹进行同步"],
});
return;
}
folderSyncItem.disable();
const r = await syncFolderRequest.run({
file_id: file.file_id,
drive_id: view.params.id,
});
folderSyncItem.enable();
if (r.error) {
app.tip({
text: ["同步失败", r.error.message],
});
return;
}
fileMenu.hide();
app.tip({
text: ["开始同步"],
});
createJob({
job_id: r.data.job_id,
});
},
});
const fileMenu = new DropdownMenuCore({
side: "right",
align: "start",
Expand All @@ -219,6 +261,7 @@ export const DriveProfilePage: ViewComponent = (props) => {
// router.push(`/play/${file.file_id}`);
},
}),
folderSyncItem,
folderDeletingItem,
],
onHidden() {
Expand Down
3 changes: 2 additions & 1 deletion src/pages/movie/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ export const MovieManagePage: ViewComponent = (props) => {
<div class="overflow-hidden mr-2 rounded-sm">
<LazyImage class="w-[180px] h-[272px]" src={poster_path} alt={name} />
</div>
<div class="flex-1 p-4">
<div class="flex-1 w-0 p-4">

<h2 class="text-2xl text-slate-800">{name}</h2>
<div class="mt-2 overflow-hidden text-ellipsis">
<p class="text-slate-700 break-all whitespace-pre-wrap truncate line-clamp-4">
Expand Down
116 changes: 106 additions & 10 deletions src/pages/movie/profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@
import { For, Show, createSignal, onMount } from "solid-js";
import { ArrowLeft } from "lucide-solid";

import { MovieProfile, delete_movie, fetch_movie_profile, update_movie_profile } from "@/services";
import {
MovieProfile,
delete_movie,
fetch_movie_profile,
parse_video_file_name,
update_movie_profile,
upload_subtitle_for_movie,
} from "@/services";
import { Button, Dialog, Skeleton, LazyImage, ScrollView, Input } from "@/components/ui";
import { TMDBSearcherDialog } from "@/components/TMDBSearcher/dialog";
import { TMDBSearcherDialogCore } from "@/components/TMDBSearcher/store";
import { TMDBSearcherDialog, TMDBSearcherDialogCore } from "@/components/TMDBSearcher";
import { DialogCore, ButtonCore, ScrollViewCore, InputCore } from "@/domains/ui";
import { RequestCore } from "@/domains/request";
import { ViewComponent } from "@/types";
import { appendAction, homeLayout, mediaPlayingPage, rootView } from "@/store";
import { SelectionCore } from "@/domains/cur";

export const MovieProfilePage: ViewComponent = (props) => {
const { app, view } = props;
Expand All @@ -37,18 +44,102 @@ export const MovieProfilePage: ViewComponent = (props) => {
profileRequest.reload();
},
});
const filenameParseRequest = new RequestCore(parse_video_file_name, {
onLoading(loading) {
subtitleUploadDialog.okBtn.setLoading(loading);
},
});
const uploadRequest = new RequestCore(upload_subtitle_for_movie, {
onLoading(loading) {
subtitleUploadDialog.okBtn.setLoading(loading);
},
onSuccess() {
app.tip({
text: ["字幕上传成功"],
});
subtitleUploadDialog.hide();
},
onFailed(error) {
app.tip({
text: ["字幕上传失败", error.message],
});
},
});
const subtitleValues = new SelectionCore<{ drive_id: string; lang: string; file: File }>();
const subtitleUploadInput = new InputCore({
defaultValue: [],
placeholder: "上传字幕文件",
type: "file",
onChange(v) {
console.log(v);
async onChange(v) {
const file = v[0];
if (!file) {
return;
}
if (!profileRequest.response) {
app.tip({
text: ["请等待详情加载完成"],
});
return;
}
if (profileRequest.response.sources.length === 0) {
app.tip({
text: ["必须包含至少一个视频源"],
});
return;
}
const { name } = file;
const r = await filenameParseRequest.run({ name, keys: ["subtitle_lang"] });
if (r.error) {
app.tip({
text: ["文件名解析失败"],
});
return;
}
const { subtitle_lang } = r.data;
if (!subtitle_lang) {
app.tip({
text: ["文件名中没有解析出字幕语言"],
});
return;
}
const sources = profileRequest.response.sources;
const reference_id = sources[0].drive.id;
// 使用 every 方法遍历数组,检查每个元素的 drive.id 是否和参考 id 相同
const all_ids_equal = sources.every((source) => source.drive.id === reference_id);
if (!all_ids_equal) {
app.tip({
text: ["视频源在多个云盘内,请手动选择上传至哪个云盘"],
});
return;
}
subtitleValues.select({
drive_id: reference_id,
file,
lang: subtitle_lang,
});
},
});
const subtitleUploadBtn = new ButtonCore({
onClick() {
subtitleUploadDialog.show();
},
});
const subtitleUploadDialog = new DialogCore({
title: "上传字幕",
onOk() {
// 开始上传字幕
if (!subtitleValues.value) {
app.tip({
text: ["请先上传字幕文件"],
});
return;
}
const { drive_id, lang, file } = subtitleValues.value;
uploadRequest.run({
movie_id: view.params.id,
drive_id,
lang,
file,
});
},
});
const movieDeletingBtn = new ButtonCore({
Expand Down Expand Up @@ -115,7 +206,7 @@ export const MovieProfilePage: ViewComponent = (props) => {

const [profile, setProfile] = createSignal<MovieProfile | null>(null);

view.onShow(() => {
onMount(() => {
const { id } = view.params;
profileRequest.run({ movie_id: id });
});
Expand Down Expand Up @@ -181,13 +272,18 @@ export const MovieProfilePage: ViewComponent = (props) => {
<div class="relative z-3 mt-4">
<div class="flex items-center space-x-4">
<Button store={movieRefreshDialogShowBtn}>修改详情</Button>
<Button store={movieDeletingBtn}>删除</Button>
<Button store={movieDeletingBtn} variant="subtle">
删除
</Button>
<Button store={subtitleUploadBtn} variant="subtle">
上传字幕
</Button>
</div>
<div class="mt-8 text-2xl">可播放源</div>
<div class="mt-4 space-y-2">
<For each={profile()?.sources}>
{(source) => {
const { file_id, file_name, parent_paths } = source;
const { file_id, file_name, parent_paths, drive } = source;
return (
<div
class=""
Expand All @@ -200,7 +296,7 @@ export const MovieProfilePage: ViewComponent = (props) => {
}}
>
<div class="">
<div class="">
<div class="" title={`[${drive.name}]${parent_paths}/${file_name}`}>
{parent_paths}/{file_name}
</div>
</div>
Expand Down
Loading

0 comments on commit 0a13718

Please sign in to comment.