add tactic import and duplication in home page
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
eef1e16830
commit
a1f8ae5017
After Width: | Height: | Size: 599 B |
@ -0,0 +1,109 @@
|
|||||||
|
import { Fetcher } from "../app/Fetcher.ts"
|
||||||
|
import {
|
||||||
|
StepInfoNode,
|
||||||
|
Tactic,
|
||||||
|
TacticInfo,
|
||||||
|
TacticStep,
|
||||||
|
} from "../model/tactic/TacticInfo.ts"
|
||||||
|
import { APITacticService } from "../service/APITacticService.ts"
|
||||||
|
import {
|
||||||
|
TacticContext,
|
||||||
|
TacticService,
|
||||||
|
} from "../service/MutableTacticService.ts"
|
||||||
|
import { countSteps } from "./StepsDomain.ts"
|
||||||
|
|
||||||
|
export function importTacticFromFile(
|
||||||
|
fetcher: Fetcher,
|
||||||
|
blob: Blob,
|
||||||
|
onSuccess: (tactic: TacticInfo) => void,
|
||||||
|
onError: (e: Error | unknown) => void = console.error,
|
||||||
|
) {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onloadend = async (e) => {
|
||||||
|
const jsonString = e.target!.result as string
|
||||||
|
|
||||||
|
let tactic
|
||||||
|
try {
|
||||||
|
tactic = await importTactic(fetcher, JSON.parse(jsonString))
|
||||||
|
} catch (e) {
|
||||||
|
onError(e)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
onSuccess(tactic)
|
||||||
|
}
|
||||||
|
reader.readAsText(blob)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function importTactic(
|
||||||
|
fetcher: Fetcher,
|
||||||
|
tactic: Tactic,
|
||||||
|
): Promise<TacticInfo> {
|
||||||
|
const response = await fetcher.fetchAPI(
|
||||||
|
"tactics",
|
||||||
|
{
|
||||||
|
name: tactic.name,
|
||||||
|
courtType: tactic.courtType,
|
||||||
|
},
|
||||||
|
"POST",
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!response.ok) throw Error("Received unsuccessful response from API.")
|
||||||
|
|
||||||
|
const { id, rootStepId } = await response.json()
|
||||||
|
|
||||||
|
const service = new APITacticService(fetcher, id)
|
||||||
|
|
||||||
|
await service.saveContent(rootStepId, tactic.root.content)
|
||||||
|
|
||||||
|
async function importStepChildren(parent: TacticStep, parentId: number) {
|
||||||
|
return await Promise.all(
|
||||||
|
parent.children.map(async (child) => {
|
||||||
|
const result = await service.addStep(parentId, child.content)
|
||||||
|
if (typeof result === "string") throw Error(result)
|
||||||
|
await importStepChildren(child, result.id)
|
||||||
|
return result
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootStepNode: StepInfoNode = {
|
||||||
|
id: rootStepId,
|
||||||
|
children: await importStepChildren(tactic.root, rootStepId),
|
||||||
|
}
|
||||||
|
|
||||||
|
return { courtType: tactic.courtType, name: tactic.name, id, rootStepNode }
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadPlainTactic(
|
||||||
|
context: TacticContext,
|
||||||
|
service: TacticService,
|
||||||
|
onProgress: (p: number) => void = () => {},
|
||||||
|
): Promise<Tactic> {
|
||||||
|
const tree = context.stepsTree
|
||||||
|
|
||||||
|
const treeSize = countSteps(tree)
|
||||||
|
const totalStepsCompleted = new Uint16Array(1)
|
||||||
|
|
||||||
|
async function transformToStep(
|
||||||
|
stepInfoNode: StepInfoNode,
|
||||||
|
): Promise<TacticStep> {
|
||||||
|
const contentResult = await service.getContent(stepInfoNode.id)
|
||||||
|
if (typeof contentResult === "string") throw Error(contentResult)
|
||||||
|
|
||||||
|
Atomics.add(totalStepsCompleted, 0, 1)
|
||||||
|
onProgress((Atomics.load(totalStepsCompleted, 0) / treeSize) * 100)
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: contentResult,
|
||||||
|
children: await Promise.all(
|
||||||
|
stepInfoNode.children.map(transformToStep),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: context.name,
|
||||||
|
courtType: context.courtType,
|
||||||
|
root: await transformToStep(tree),
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue