Skip to content

Commit

Permalink
+ complete change in the way projects are stored, to provide unlimite…
Browse files Browse the repository at this point in the history
…d storage capacity
  • Loading branch information
zonetecde committed Oct 5, 2024
1 parent 127b4f7 commit db3f3fe
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 40 deletions.
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "Quran Caption",
"version": "1.9.0"
"version": "2.1.0"
},
"tauri": {
"allowlist": {
Expand Down
6 changes: 4 additions & 2 deletions src/lib/components/subtitles/VersePicker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
if (element.isLastWordInVerse) {
// Go to next verse
verseNumber += 1;
verseNumberInInput += 1;
if (verseNumberInInput < $Mushaf.surahs[surahNumber - 1].verses.length) {
verseNumber += 1;
verseNumberInInput += 1;
}
}
break;
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ext/GlobalVariables.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const SOFTWARE_VERSION = 'v1.9';
export const SOFTWARE_VERSION = 'v2.1';
export const GITHUB_API_URL =
'https://api.github.com/repos/zonetecde/QuranCaption-2/releases/latest';
export const GITHUB_REPO_LINK = 'https://github.com/zonetecde/QuranCaption-2';
Expand Down
35 changes: 35 additions & 0 deletions src/lib/ext/VersionFix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ProjectDesc } from '$lib/models/Project';

/**
* From v2.0.0 to v2.1.0, the project system was changed.
*/
export function newProjectSystemMigration() {
const projects: any[] = JSON.parse(localStorage.getItem('projects') || '[]');
if (projects.length > 0) {
if (projects[0].timeline !== undefined) {
// backup and download the old projects
const data = JSON.stringify(projects, null, 2);
const blob = new Blob([data], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'BACKUP FILE IN CASE EVERYTHING BROKE.qcb';
a.click();

// Make each project occupy one different localstorage item
let projectsDesc: ProjectDesc[] = [];
for (let i = 0; i < projects.length; i++) {
const element = projects[i];

localStorage.setItem(element.id, JSON.stringify(element));
projectsDesc.push({
name: element.name,
updatedAt: element.updatedAt,
id: element.id
});
}

localStorage.setItem('projects', JSON.stringify(projectsDesc));
}
}
}
6 changes: 6 additions & 0 deletions src/lib/models/Project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import type Timeline from './Timeline';
import Id from '../ext/Id';
import { cursorPosition, zoom } from '../stores/TimelineStore';

export interface ProjectDesc {
id: string;
name: string;
updatedAt: Date;
}

/**
* Represents a project.
*/
Expand Down
45 changes: 28 additions & 17 deletions src/lib/stores/ProjectStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type Project from '$lib/models/Project';
import { get, writable, type Writable } from 'svelte/store';
import { cursorPosition, scrollPosition, zoom } from './TimelineStore';
import Id from '$lib/ext/Id';
import type { ProjectDesc } from '$lib/models/Project';

export const currentProject: Writable<Project> = writable();

Expand Down Expand Up @@ -107,23 +108,21 @@ export function createBlankProject(name: string): Project {
* @param id - The ID of the project to delete.
* @returns An array of user projects.
*/
export function delProject(id: string): Project[] {
const projects = getUserProjects();
const index = projects.findIndex((p) => p.id === id);
export function delProject(id: string): ProjectDesc[] {
localStorage.removeItem(id);

if (index !== -1) {
projects.splice(index, 1);
localStorage.setItem('projects', JSON.stringify(projects));
}
let userProjects = getUserProjects();
userProjects = userProjects.filter((x) => x.id !== id);
localStorage.setItem('projects', JSON.stringify(userProjects));

return projects;
return userProjects;
}

/**
* Retrieves the user's projects from local storage.
* @returns An array of user projects.
*/
export function getUserProjects(): Project[] {
export function getUserProjects(): ProjectDesc[] {
return JSON.parse(localStorage.getItem('projects') || '[]');
}

Expand All @@ -133,33 +132,45 @@ export function getUserProjects(): Project[] {
* @returns The project with the specified ID, or undefined if not found.
*/
export function getProjectById(id: string): Project | undefined {
return getUserProjects().find((p) => p.id === id);
const projJson = localStorage.getItem(id);
if (projJson) return JSON.parse(projJson);
else return createBlankProject('undefined project');
}

/**
* Updates the user's projects in local storage.
* @param project - The project to update.
*/
export function updateUsersProjects(project: Project): void {
if (project === undefined) return; // No project is open
export function updateUsersProjects(project: Project): ProjectDesc[] {
const projects: ProjectDesc[] = getUserProjects();

if (project === undefined) return projects; // No project is open

project.projectSettings.zoom = get(zoom);
project.projectSettings.cursorPosition = get(cursorPosition);
project.projectSettings.scrollLeft = get(scrollPosition);

const projects = getUserProjects();

const index = projects.findIndex((p) => p.id === project.id);
if (index === -1) {
if (projects.find((p) => p.name === project.name)) {
project.name = project.name + ' - New';
}

projects.push(project);
projects.push({
id: project.id,
name: project.name,
updatedAt: project.updatedAt
});
} else {
projects[index] = project;
projects[index] = {
id: project.id,
name: project.name,
updatedAt: project.updatedAt
};
}

//localStorage.removeItem('projects');
localStorage.setItem(project.id, JSON.stringify(project));
localStorage.setItem('projects', JSON.stringify(projects));

return projects;
}
58 changes: 39 additions & 19 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
createBlankProject,
currentProject,
delProject,
getProjectById,
getUserProjects,
updateUsersProjects
} from '$lib/stores/ProjectStore';
Expand All @@ -24,16 +25,20 @@
import { invoke } from '@tauri-apps/api/tauri';
import { open } from '@tauri-apps/api/dialog';
import { addAssets } from '$lib/models/Asset';
import type { ProjectDesc } from '$lib/models/Project';
import { newProjectSystemMigration } from '$lib/ext/VersionFix';
let createProjectVisibility = false;
let projectName = 'New Project';
let userProjects: Project[] = [];
let userProjectsDesc: ProjectDesc[] = [];
let searchText = '';
onMount(async () => {
userProjects = getUserProjects();
newProjectSystemMigration();
userProjectsDesc = getUserProjects();
// Check if a new version is available
const response = await fetch(GITHUB_API_URL);
Expand Down Expand Up @@ -69,21 +74,21 @@
updateUsersProjects(project); // Save the project to the local storage
openProject(project); // Open the project
openProject(project.id); // Open the project
}
/**
* Open a project
*/
function openProject(project: Project) {
window.location.href = `/editor?${project.id}`; // Redirect to the editor page
function openProject(projectId: string) {
window.location.href = `/editor?${projectId}`; // Redirect to the editor page
}
/**
* Handle delete project
*/
function handleDelProject(id: string) {
userProjects = delProject(id);
userProjectsDesc = delProject(id);
}
/**
Expand All @@ -97,16 +102,24 @@
project.id = Id.generate(); // Generate a new id for the project
updateUsersProjects(project); // Save the project to the local storage
userProjectsDesc = updateUsersProjects(project); // Save the project to the local storage
openProject(project); // Open the project
openProject(project.id); // Open the project
}
}
/**
* Handle backup all projects button clicked
*/
function handleBackupAllProjectsButtonClicked() {
let userProjects: Project[] = [];
for (let i = 0; i < userProjectsDesc.length; i++) {
const element = userProjectsDesc[i];
userProjects.push(JSON.parse(localStorage.getItem(element.id)!));
}
const data = JSON.stringify(userProjects, null, 2);
const blob = new Blob([data], { type: 'application/json' });
Expand All @@ -130,16 +143,17 @@
projects.forEach((project: Project) => {
// if project id already exists, replace it if the updatedAt is more recent
const existingProject = userProjects.find((p) => p.id === project.id);
const existingProject = userProjectsDesc.find((p) => p.id === project.id);
if (existingProject && new Date(existingProject.updatedAt) > new Date(project.updatedAt)) {
userProjects = userProjects.map((p) => (p.id === project.id ? project : p));
} else {
userProjectsDesc = userProjectsDesc.map((p) => (p.id === project.id ? project : p));
updateUsersProjects(project);
} else if (!existingProject) {
// Project does not exist, add it
updateUsersProjects(project);
}
});
userProjects = getUserProjects();
userProjectsDesc = getUserProjects();
}
}
</script>
Expand All @@ -149,7 +163,7 @@
<h1 class="text-4xl font-bold text-center schibstedGrotesk">Quran Caption</h1>

<div class="mt-10 relative">
<p class="text-xl pl-3">Project{userProjects.length > 1 ? 's' : ''} :</p>
<p class="text-xl pl-3">Project{userProjectsDesc.length > 1 ? 's' : ''} :</p>

<input
type="text"
Expand All @@ -160,15 +174,15 @@

<div
class={'mt-2 h-40 bg-default border-4 border-[#141414] rounded-xl p-3 flex gap-4 flex-wrap overflow-y-auto ' +
(userProjects.length >= 4 ? 'justify-evenly h-80' : '')}
(userProjectsDesc.length >= 4 ? 'justify-evenly h-80' : '')}
>
{#each userProjects.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()) as project}
{#each userProjectsDesc.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()) as project}
{#if searchText === '' || project.name.toLowerCase().includes(searchText.toLowerCase())}
<div class="w-56 h-32 bg-[#2e2f36] rounded-xl relative group">
<button class="flex flex-col p-3" on:click={() => openProject(project)}>
<button class="flex flex-col p-3" on:click={() => openProject(project.id)}>
<p>{project.name}</p>
<p class="absolute bottom-1 text-sm">
{new Date(project.createdAt).toLocaleString()}
{new Date(project.updatedAt).toLocaleString()}
</p>
</button>

Expand Down Expand Up @@ -200,8 +214,14 @@
// window text prompt
const newName = prompt('Enter the new name of the project', project.name);
if (newName) {
project.name = newName;
updateUsersProjects(project);
userProjectsDesc = userProjectsDesc.map((x) =>
x.id === project.id ? { ...x, name: newName } : x
);
let _project = getProjectById(project.id);
// @ts-ignore
_project.name = newName;
// @ts-ignores
updateUsersProjects(_project);
}
}}
>
Expand Down

0 comments on commit db3f3fe

Please sign in to comment.