移植 Axolotl 的拖拽式实例分组界面到 Starlight,接入阶段1的规范化分组后端: - 新增 helpers/analytics.ts(trackEvent 遥测桩) - 补全 helpers/instance-groups.ts(6 个 invoke 包装) - 新增 composables/useInstanceGroups.ts(分组状态 + 事件监听) - 升级 composables/useGridGrouping.ts(排序方向 isSortAscending/toggleSortDirection) - helpers/events.js 补 instance_groups_listener(对接 instance_groups_changed 事件) - 新增 components/ui/library/DraggableInstanceCard.vue - 新增 components/ui/library/InstanceGroup.vue(并补 group-drag-handle 修复组拖拽重排) - 新增 components/ui/modal/InstanceGroupModal.vue - GridDisplay.vue 替换为 Axolotl 拖拽版(DragDropProvider + vuedraggable) - 补 en-US/zh-CN i18n 键各 39 条
This commit is contained in:
1 parent
253141b6ff
commit
f253d5529b
11 files changed
+2214
-297
No files matched your search
@@ -0,0 +1,75 @@
|
||||
interface InstanceProperties {
|
||||
loader: string
|
||||
game_version: string
|
||||
}
|
||||
|
||||
interface ProjectProperties extends InstanceProperties {
|
||||
id: string
|
||||
project_type: string
|
||||
}
|
||||
|
||||
type AnalyticsEventMap = {
|
||||
Launched: { version: string; dev: boolean; onboarded: boolean }
|
||||
PageView: { path: string; fromPath: string; failed: unknown }
|
||||
InstanceCreate: { source: string }
|
||||
InstanceCreateStart: { source: string }
|
||||
InstanceStart: InstanceProperties & { source: string }
|
||||
InstanceStop: Partial<InstanceProperties> & { source?: string }
|
||||
InstanceDuplicate: InstanceProperties
|
||||
InstanceRepair: InstanceProperties
|
||||
InstanceSetIcon: Record<string, never>
|
||||
InstanceRemoveIcon: Record<string, never>
|
||||
InstanceUpdateAll: InstanceProperties & { count: number; selected: boolean }
|
||||
InstanceProjectUpdate: InstanceProperties & { id: string; name: string; project_type: string }
|
||||
InstanceProjectDisable: InstanceProperties & {
|
||||
id: string
|
||||
name: string
|
||||
project_type: string
|
||||
disabled: boolean
|
||||
}
|
||||
InstanceProjectRemove: InstanceProperties & { id: string; name: string; project_type: string }
|
||||
ProjectInstall: ProjectProperties & { version_id: string; title: string; source: string }
|
||||
ProjectInstallStart: { source: string }
|
||||
PackInstall: { id: string; version_id: string; title: string; source: string }
|
||||
PackInstallStart: Record<string, never>
|
||||
AccountLogIn: { source?: string }
|
||||
AccountLogOut: Record<string, never>
|
||||
JavaTest: { path: string; success: boolean }
|
||||
JavaManualSelect: { version: string }
|
||||
JavaAutoDetect: { path: string; version: string }
|
||||
GalleryImageNext: { project_id: string; url: string }
|
||||
GalleryImagePrevious: { project_id: string; url: unknown }
|
||||
GalleryImageExpand: { project_id: string; url: string }
|
||||
}
|
||||
|
||||
export type AnalyticsEvent = keyof AnalyticsEventMap
|
||||
|
||||
let optedIn = false
|
||||
let debugEnabled = false
|
||||
|
||||
export const initAnalytics = () => {
|
||||
optedIn = true
|
||||
}
|
||||
|
||||
export const debugAnalytics = () => {
|
||||
debugEnabled = true
|
||||
}
|
||||
|
||||
export const optOutAnalytics = () => {
|
||||
optedIn = false
|
||||
}
|
||||
|
||||
export const optInAnalytics = () => {
|
||||
optedIn = true
|
||||
}
|
||||
|
||||
type OptionalArgs<T> = Record<string, never> extends T ? [properties?: T] : [properties: T]
|
||||
|
||||
export const trackEvent = <E extends AnalyticsEvent>(
|
||||
eventName: E,
|
||||
...args: OptionalArgs<AnalyticsEventMap[E]>
|
||||
) => {
|
||||
if (optedIn && debugEnabled) {
|
||||
console.debug('[Starlight telemetry disabled]', eventName, args[0])
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,16 @@ export async function instance_bulk_update_progress_listener(callback) {
|
||||
return await listen('instance_bulk_update_progress', (event) => callback(event.payload))
|
||||
}
|
||||
|
||||
/// Payload for the 'instance_groups_changed' event
|
||||
/*
|
||||
InstanceGroupsChangedPayload {
|
||||
instance_ids: string[]
|
||||
}
|
||||
*/
|
||||
export async function instance_groups_listener(callback) {
|
||||
return await listen('instance_groups_changed', (event) => callback(event.payload))
|
||||
}
|
||||
|
||||
export async function install_job_listener(callback) {
|
||||
return await listen('install_job', (event) => callback(event.payload))
|
||||
}
|
||||
|
||||
@@ -1 +1,46 @@
|
||||
export const MAX_INSTANCE_GROUP_NAME_LENGTH = 256
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
export const MAX_INSTANCE_GROUP_NAME_LENGTH = 256
|
||||
|
||||
export type InstanceGroupDefinition = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
export type InstanceGroupMembershipUpdate = {
|
||||
instance_id: string
|
||||
group_ids: string[]
|
||||
}
|
||||
|
||||
export async function list_groups(): Promise<InstanceGroupDefinition[]> {
|
||||
return await invoke('plugin:instance|instance_list_groups')
|
||||
}
|
||||
|
||||
export async function create_group(name: string): Promise<InstanceGroupDefinition> {
|
||||
return await invoke('plugin:instance|instance_create_group', { name })
|
||||
}
|
||||
|
||||
export async function rename_group(id: string, newName: string): Promise<InstanceGroupDefinition> {
|
||||
return await invoke('plugin:instance|instance_rename_group', {
|
||||
id,
|
||||
newName,
|
||||
})
|
||||
}
|
||||
|
||||
export async function delete_group(id: string): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_delete_group', { id })
|
||||
}
|
||||
|
||||
export async function set_group_order(group_ids: string[]): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_set_group_order', {
|
||||
groupIds: group_ids,
|
||||
})
|
||||
}
|
||||
|
||||
export async function set_group_memberships(
|
||||
updates: InstanceGroupMembershipUpdate[],
|
||||
): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_set_group_memberships', {
|
||||
updates,
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user