Skip to content

Commit

Permalink
Project Loading ...
Browse files Browse the repository at this point in the history
  • Loading branch information
ltouroumov committed Sep 20, 2024
1 parent 6d5f5c9 commit fdb4b2b
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 36 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
],
"plugins": ["@typescript-eslint", "nuxt", "import", "unused-imports"],
"rules": {
// Interferes with unused-import
"@typescript-eslint/no-unused-vars": "off",
"no-console": "off",
"vue/multi-word-component-names": "off",
"sort-imports": [
Expand Down
26 changes: 8 additions & 18 deletions components/LoadProject.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

<script setup lang="ts">
import { useProjectStore } from '~/composables/store/project';
import { readFileContents } from '~/composables/utils';
const { loadProject, unloadProject } = useProjectStore();
const { isLoaded } = useProjectStore();
Expand Down Expand Up @@ -56,7 +57,7 @@ const checkCanLoad = () => {
checkCanLoad();
const loadProjectFile = () => {
const loadProjectFile = async () => {
if (fileInput.value && fileInput.value.files) {
const [file] = fileInput.value.files;
if (!file) {
Expand All @@ -66,25 +67,14 @@ const loadProjectFile = () => {
isLoading.value = true;
const reader = new FileReader();
reader.addEventListener('load', () => {
if (reader.result && typeof reader.result === 'string') {
const data = JSON.parse(reader.result);
try {
const data = await readFileContents(file);
if (data && typeof data === 'string') {
isLoading.value = false;
if (isLoaded) {
unloadProject();
}
loadProject(data, file.name);
unloadProject();
await loadProject(data, file.name);
}
});
reader.addEventListener('error', () => {
error.value = reader.error?.message ?? 'An error occurred';
isLoading.value = false;
});
try {
reader.readAsText(file);
} catch (e: unknown) {
} catch (e) {
isLoading.value = false;
if (e instanceof Error) {
error.value = e.message;
Expand Down
21 changes: 8 additions & 13 deletions components/viewer/ProjectMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@
</template>

<script setup lang="ts">
import { Project } from '~/composables/project';
import { useProjectRefs, useProjectStore } from '~/composables/store/project';
import { useViewerStore } from '~/composables/store/viewer';
import { bufferToString } from '~/composables/utils';
import { ViewerProjectList } from '~/composables/viewer';
const isLoading = ref<boolean>(false);
Expand All @@ -57,7 +57,7 @@ const loadRemoteFile = async ({ target }: MouseEvent) => {
const response = await fetch(fileURL);
let result: Project;
let result: string;
if (response.ok) {
const reader = response.body!.getReader();
Expand Down Expand Up @@ -91,21 +91,16 @@ const loadRemoteFile = async ({ target }: MouseEvent) => {
pos += chunk.length;
}
const bodyText = new TextDecoder('utf-8').decode(bodyBytes);
result = JSON.parse(bodyText);
const bodyText = bufferToString(bodyBytes);
result = bodyText;
} else {
return;
}
if (isLoaded.value) {
unloadProject();
}
// Wait for the unloadProject to finish before loading the new project
await nextTick(() => {
loadProject(result, fileURL);
toggleProjectMenu(false);
isLoading.value = false;
});
unloadProject();
await loadProject(result, fileURL);
toggleProjectMenu(false);
isLoading.value = false;
}
};
</script>
Expand Down
6 changes: 5 additions & 1 deletion composables/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export type PointType = {
};

export type Project = {
$projectId?: string;
rows: ProjectRow[];
backpack: ProjectRow[];
pointTypes: PointType[];
Expand All @@ -218,5 +219,8 @@ export type Project = {

export type ProjectFile = {
data: Project;
file: string;
fileName: string;
projectId: string;
projectName: string;
projectHash: string;
};
22 changes: 19 additions & 3 deletions composables/store/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { useToast } from 'vue-toastification';
import { buildConditions } from '~/composables/conditions';
import {
PointType,
Project,
ProjectFile,
ProjectObj,
ProjectRow,
Score,
} from '~/composables/project';
import { bufferToHex, stringToBuffer } from '~/composables/utils';

export type Selections = Record<string, number>;
type Transform = (sel: Selections) => Selections;
Expand Down Expand Up @@ -77,8 +77,24 @@ export const useProjectStore = defineStore('project', () => {
});

const isLoaded = computed(() => !!project.value);
const loadProject = (data: Project, file: string) => {
project.value = { data, file };
const loadProject = async (fileContents: string, fileName: string) => {
const hashBytes = await crypto.subtle.digest(
'SHA-1',
stringToBuffer(fileContents),
);
const hashHex = bufferToHex(hashBytes);

const data: Project = JSON.parse(fileContents);
const projectFile: ProjectFile = {
data: data,
fileName: fileName,
projectId: data?.$projectId ?? hashHex,
projectName: data.rows[0].title,
projectHash: hashHex,
};
console.log(projectFile);
project.value = projectFile;
selected.value = {};
};
const unloadProject = () => {
project.value = null;
Expand Down
38 changes: 38 additions & 0 deletions composables/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,41 @@ export const timeIt =
console.log(`[TIME] ${name}: ${end - start}ms`);
}
};

export const bufferToHex = (buffer: ArrayBuffer): string => {
const buf = new Uint8Array(buffer);
const acc = [];
for (let i = 0; i < buf.length; i++) {
acc.push(buf[i].toString(16).padStart(2, '0'));
}
return acc.join('');
};

const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder('utf-8');

export const stringToBuffer = (value: string): Uint8Array => {
return textEncoder.encode(value);
};
export const bufferToString = (buffer: ArrayBuffer) => {
return textDecoder.decode(buffer);
};

export const readFileContents = (file: Blob) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.addEventListener('load', () => {
resolve(reader.result);
});
reader.addEventListener('error', (event) => {
event.preventDefault();
reject(new Error('Reader Failed'));
});

try {
reader.readAsText(file);
} catch (e: unknown) {
reject(e);
}
});
};
2 changes: 1 addition & 1 deletion nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
app: {
baseURL: '/cyoa-editor/',
baseURL: process.env.NODE_ENV === 'production' ? '/cyoa-editor/' : '/',
buildAssetsDir: 'assets',
head: {
title: 'Interactive CYOA',
Expand Down

0 comments on commit fdb4b2b

Please sign in to comment.