Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[project-library-manage] ライブラリ管理画面のデータの持ち方などをリファクタリング #1584

Open
wants to merge 13 commits into
base: project-library-manage
Choose a base branch
from
184 changes: 98 additions & 86 deletions src/components/LibraryManageDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,13 @@
class="library-list"
>
<q-item
v-for="library of downloadableLibraries[engineId]"
:key="library.uuid"
v-for="(library, libraryUuid) in downloadableLibraries[
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
engineId
]"
:key="libraryUuid"
class="q-pa-none library-item"
:class="
selectedLibrary === library.uuid && 'selected-library-item'
selectedLibrary === libraryUuid && 'selected-library-item'
"
>
<div class="library-item-inner">
Expand All @@ -79,16 +81,16 @@
outline
text-color="display"
class="text-no-wrap q-ma-sm"
:disable="isLatest(engineId, library)"
:disable="
library.type === 'installed' && library.isLatest
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
"
@click.stop="installLibrary(engineId, library)"
>
{{
isLatest(engineId, library)
// TODO: customInstalledについて考慮
library.type === "installed" && library.isLatest
? "最新版です"
: installedLibraries[engineId].find(
(installedLibrary) =>
installedLibrary.uuid === library.uuid
)
: library.type === "installed" && !library.isLatest
? "アップデート"
: "インストール"
}}
Expand All @@ -97,7 +99,11 @@
outline
text-color="warning"
class="text-no-wrap q-ma-sm"
:disable="!isUninstallable(engineId, library)"
:disable="
(library.type !== 'downloadable' &&
!library.uninstallable) ||
library.type === 'downloadable'
"
@click.stop="uninstallLibrary(engineId, library)"
>
アンインストール
Expand Down Expand Up @@ -164,18 +170,34 @@ import {
SpeakerId,
StyleId,
} from "@/type/preload";
import { DownloadableLibrary, InstalledLibrary } from "@/openapi";
import {
DownloadableLibrary as EngineDownloadableLibrary,
InstalledLibrary as EngineInstalledLibrary,
} from "@/openapi";

type BrandedDownloadableLibrary = Omit<
DownloadableLibrary,
type DownloadableLibrary = Omit<
EngineDownloadableLibrary,
"speakers" | "uuid"
> & {
uuid: LibraryId;
speakers: CharacterInfo[];
};

type BrandedInstalledLibrary = BrandedDownloadableLibrary &
Pick<InstalledLibrary, "uninstallable">;
type LibraryType = DownloadableLibrary &
(
| {
type: "downloadable";
Hiroshiba marked this conversation as resolved.
Show resolved Hide resolved
}
| {
type: "installed";
isLatest: boolean;
uninstallable: boolean;
}
| {
type: "customInstalled";
uninstallable: boolean;
}
);

const $q = useQuasar();

Expand Down Expand Up @@ -213,35 +235,8 @@ const closeDialog = () => {
};

const downloadableLibraries = ref<
Record<EngineId, BrandedDownloadableLibrary[]>
Record<EngineId, Record<LibraryId, LibraryType>>
>({});
const installedLibraries = ref<Record<EngineId, BrandedInstalledLibrary[]>>({});

const isLatest = (engineId: EngineId, library: BrandedDownloadableLibrary) => {
const installedLibrary = installedLibraries.value[engineId].find(
(installedLibrary) => installedLibrary.uuid === library.uuid
);
// ライブラリがインストールされていない場合はfalseとする
if (!installedLibrary) {
return false;
}
// installedLibrary.versionがlibrary.versionと等しいか、それより大きい場合はlatest
return semver.gte(installedLibrary.version, library.version);
};

const isUninstallable = (
engineId: EngineId,
library: BrandedDownloadableLibrary
) => {
const installedLibrary = installedLibraries.value[engineId].find(
(installedLibrary) => installedLibrary.uuid === library.uuid
);
// ライブラリがインストールされていない場合はfalseとする
if (!installedLibrary) {
return false;
}
return installedLibrary.uninstallable;
};

const fetchStatuses = ref<
Record<EngineId, "fetching" | "success" | "error" | undefined>
Expand Down Expand Up @@ -271,7 +266,7 @@ const isValidHttpUrl = (url: string): boolean => {

const libraryInfoToCharacterInfos = (
engineId: EngineId,
libraryInfo: DownloadableLibrary | InstalledLibrary
libraryInfo: EngineDownloadableLibrary | EngineInstalledLibrary
): CharacterInfo[] => {
return libraryInfo.speakers.map((speaker) => {
const portrait = speaker.speakerInfo.portrait;
Expand Down Expand Up @@ -323,7 +318,7 @@ watch(modelValueComputed, async (newValue) => {
return;
}
fetchStatuses.value[engineId] = "fetching";
const fetchResult = await store
const convertedDownloadableLibraries = await store
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここもdownloadableいらないはず

.dispatch("INSTANTIATE_ENGINE_CONNECTOR", {
engineId,
})
Expand All @@ -335,58 +330,81 @@ watch(modelValueComputed, async (newValue) => {
instance.invoke("installedLibrariesInstalledLibrariesGet")({}),
])
)
.then(([downloadableLibraries, installedLibraries]): [
BrandedDownloadableLibrary[],
BrandedInstalledLibrary[]
] => {
fetchStatuses.value[engineId] = "success";
return [
downloadableLibraries.map((library) => {
return {
.then(
([
engineDownloadableLibraries,
engineInstalledLibraries,
]): LibraryType[] => {
fetchStatuses.value[engineId] = "success";
const convertedInstalledLibrary = Object.fromEntries(
Object.entries(engineInstalledLibraries).map(
([uuid, library]) => {
return [
LibraryId(uuid),
{
...library,
uuid: LibraryId(uuid),
speakers: libraryInfoToCharacterInfos(engineId, library),
},
];
}
)
);
Copy link
Member Author

@y-chan y-chan Sep 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

現状はconvertedInstalledLibraryを作る意味は殆ど無いですが、 #1568 で使うことになると思うので、残しておいてもいいかなーといった感じです。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

なるほどです。実際必要なのかわかってないのですが、不要そうだったら #1568 の後にもう1回リファクタリングしましょう!
(なんか辞書ダイアログのリファクタリングを思い出しますね・・・。)


// TODO: customInstalledについて考慮
return engineDownloadableLibraries.map((library) => {
const libraryBase = {
...library,
uuid: LibraryId(library.uuid),
speakers: libraryInfoToCharacterInfos(engineId, library),
};
}),
Object.entries(installedLibraries).map(([uuid, library]) => {
const installedLibrary = convertedInstalledLibrary[library.uuid];
y-chan marked this conversation as resolved.
Show resolved Hide resolved
if (installedLibrary) {
return {
...libraryBase,
type: "installed",
// installedLibrary.versionがlibrary.versionと等しいか、それより大きい場合はlatest
isLatest: semver.gte(
installedLibrary.version,
library.version
),
uninstallable: installedLibrary.uninstallable,
};
}
return {
...library,
uuid: LibraryId(uuid),
speakers: libraryInfoToCharacterInfos(engineId, library),
...libraryBase,
type: "downloadable",
};
}),
];
})
});
}
)
.catch((e) => {
fetchStatuses.value[engineId] = "error";
store.dispatch("LOG_ERROR", e);
});

if (!fetchResult) return;

const [brandedDownloadableLibraries, brandedInstalledLibraries] =
fetchResult;
downloadableLibraries.value[engineId] = brandedDownloadableLibraries;
installedLibraries.value[engineId] = brandedInstalledLibraries;
if (!convertedDownloadableLibraries) return;

const libraries = downloadableLibraries.value[engineId] || [];
const toPrimaryOrder = (library: BrandedDownloadableLibrary) => {
const localLibrary = installedLibraries.value[engineId].find(
(l) => l.uuid === library.uuid
);
// ダウンロード可能なライブラリはソートしてから代入する
const toPrimaryOrder = (library: LibraryType) => {
// アップデート > 未インストール > インストール済み の順
if (!localLibrary) {
if (library.type === "downloadable") {
return 1;
} else if (semver.gt(library.version, localLibrary?.version)) {
} else if (library.type === "installed" && !library.isLatest) {
return 2;
} else {
return 0;
}
};

libraries.sort((a, b) => {
convertedDownloadableLibraries.sort((a, b) => {
return toPrimaryOrder(b) - toPrimaryOrder(a);
});
downloadableLibraries.value[engineId] = {};
for (const downloadableLibrary of convertedDownloadableLibraries) {
downloadableLibraries.value[engineId][downloadableLibrary.uuid] =
downloadableLibrary;
}
})
);
});
Expand Down Expand Up @@ -417,9 +435,9 @@ const play = (
) => {
if (audio.src !== "") stop();

const speaker = downloadableLibraries.value[engineId]
.find((l) => l.uuid === libraryId)
?.speakers.find((s) => s.metas.speakerUuid === speakerUuid);
const speaker = downloadableLibraries.value[engineId][
libraryId
].speakers.find((s) => s.metas.speakerUuid === speakerUuid);
if (!speaker) throw new Error("speaker not found");

const styleInfo = speaker.metas.styles.find((s) => s.styleId === styleId);
Expand Down Expand Up @@ -468,10 +486,7 @@ const togglePlayOrStop = (
}
};

const installLibrary = async (
engineId: EngineId,
library: BrandedDownloadableLibrary
) => {
const installLibrary = async (engineId: EngineId, library: LibraryType) => {
selectLibraryAndSpeaker(
LibraryId(library.uuid),
SpeakerId(library.speakers[0].metas.speakerUuid)
Expand All @@ -480,10 +495,7 @@ const installLibrary = async (
// TODO: インストール処理を追加する
};

const uninstallLibrary = async (
engineId: EngineId,
library: BrandedDownloadableLibrary
) => {
const uninstallLibrary = async (engineId: EngineId, library: LibraryType) => {
y-chan marked this conversation as resolved.
Show resolved Hide resolved
selectLibraryAndSpeaker(
LibraryId(library.uuid),
SpeakerId(library.speakers[0].metas.speakerUuid)
Expand Down