Add offline mode logic for book, story, and world operations

- Integrate `OfflineContext` into book, story settings, and related components.
- Add conditional logic to toggle between server API requests and offline IPC handlers (`db:book:delete`, `db:book:story:get`, `db:location:all`, etc.).
- Refactor and update IPC handlers to accept structured data arguments for improved consistency (`data: object`).
- Ensure stricter typings in IPC handlers and frontend functions.
- Improve error handling and user feedback in both online and offline modes.
This commit is contained in:
natreex
2025-11-26 22:52:34 -05:00
parent e1abcd9490
commit 23f1592c22
15 changed files with 518 additions and 201 deletions

View File

@@ -16,10 +16,12 @@ import {configs} from "@/lib/configs";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import {BookProps} from "@/lib/models/Book"; import {BookProps} from "@/lib/models/Book";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
function BasicInformationSetting(props: any, ref: any) { function BasicInformationSetting(props: any, ref: any) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext) const {lang} = useContext<LangContextProps>(LangContext)
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {book, setBook} = useContext(BookContext); const {book, setBook} = useContext(BookContext);
@@ -114,7 +116,18 @@ function BasicInformationSetting(props: any, ref: any) {
return; return;
} }
try { try {
const response: boolean = await System.authPostToServer<boolean>('book/basic-information', { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:updateBasicInformation', {
title: title,
subTitle: subTitle,
summary: summary,
publicationDate: publicationDate,
wordCount: wordCount,
bookId: bookId
});
} else {
response = await System.authPostToServer<boolean>('book/basic-information', {
title: title, title: title,
subTitle: subTitle, subTitle: subTitle,
summary: summary, summary: summary,
@@ -122,6 +135,7 @@ function BasicInformationSetting(props: any, ref: any) {
wordCount: wordCount, wordCount: wordCount,
bookId: bookId bookId: bookId
}, userToken, lang); }, userToken, lang);
}
if (!response) { if (!response) {
errorMessage(t('basicInformationSetting.error.update')); errorMessage(t('basicInformationSetting.error.update'));
return; return;

View File

@@ -7,6 +7,7 @@ import {BookProps} from "@/lib/models/Book";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import {AlertContext, AlertContextProps} from "@/context/AlertContext"; import {AlertContext, AlertContextProps} from "@/context/AlertContext";
import AlertBox from "@/components/AlertBox"; import AlertBox from "@/components/AlertBox";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface DeleteBookProps { interface DeleteBookProps {
bookId: string; bookId: string;
@@ -15,6 +16,7 @@ interface DeleteBookProps {
export default function DeleteBook({bookId}: DeleteBookProps) { export default function DeleteBook({bookId}: DeleteBookProps) {
const {session, setSession} = useContext(SessionContext); const {session, setSession} = useContext(SessionContext);
const {lang} = useContext<LangContextProps>(LangContext) const {lang} = useContext<LangContextProps>(LangContext)
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const [showConfirmBox, setShowConfirmBox] = useState<boolean>(false); const [showConfirmBox, setShowConfirmBox] = useState<boolean>(false);
const {errorMessage} = useContext<AlertContextProps>(AlertContext) const {errorMessage} = useContext<AlertContextProps>(AlertContext)
@@ -24,7 +26,13 @@ export default function DeleteBook({bookId}: DeleteBookProps) {
async function handleDeleteBook(): Promise<void> { async function handleDeleteBook(): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>( let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:delete', {
id: bookId,
});
} else {
response = await System.authDeleteToServer<boolean>(
`book/delete`, `book/delete`,
{ {
id: bookId, id: bookId,
@@ -32,6 +40,7 @@ export default function DeleteBook({bookId}: DeleteBookProps) {
session.accessToken, session.accessToken,
lang lang
); );
}
if (response) { if (response) {
setShowConfirmBox(false); setShowConfirmBox(false);
const updatedBooks: BookProps[] = (session.user?.books || []).reduce((acc: BookProps[], book: BookProps): BookProps[] => { const updatedBooks: BookProps[] = (session.user?.books || []).reduce((acc: BookProps[], book: BookProps): BookProps[] => {

View File

@@ -9,6 +9,7 @@ import {BookContext} from "@/context/BookContext";
import CharacterDetail from "@/components/book/settings/characters/CharacterDetail"; import CharacterDetail from "@/components/book/settings/characters/CharacterDetail";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface CharacterDetailProps { interface CharacterDetailProps {
selectedCharacter: CharacterProps | null; selectedCharacter: CharacterProps | null;
@@ -46,6 +47,7 @@ const initialCharacterState: CharacterProps = {
export function CharacterComponent(props: any, ref: any) { export function CharacterComponent(props: any, ref: any) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext) const {lang} = useContext<LangContextProps>(LangContext)
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
const {errorMessage, successMessage} = useContext(AlertContext); const {errorMessage, successMessage} = useContext(AlertContext);
@@ -64,9 +66,14 @@ export function CharacterComponent(props: any, ref: any) {
async function getCharacters(): Promise<void> { async function getCharacters(): Promise<void> {
try { try {
const response: CharacterProps[] = await System.authGetQueryToServer<CharacterProps[]>(`character/list`, session.accessToken, lang, { let response: CharacterProps[];
if (isCurrentlyOffline()) {
response = await window.electron.invoke<CharacterProps[]>('db:character:list', {bookid: book?.bookId});
} else {
response = await System.authGetQueryToServer<CharacterProps[]>(`character/list`, session.accessToken, lang, {
bookid: book?.bookId, bookid: book?.bookId,
}); });
}
if (response) { if (response) {
setCharacters(response); setCharacters(response);
} }
@@ -108,10 +115,18 @@ export function CharacterComponent(props: any, ref: any) {
return; return;
} }
try { try {
const characterId: string = await System.authPostToServer<string>(`character/add`, { let characterId: string;
if (isCurrentlyOffline()) {
characterId = await window.electron.invoke<string>('db:character:create', {
bookId: book?.bookId,
character: updatedCharacter,
});
} else {
characterId = await System.authPostToServer<string>(`character/add`, {
bookId: book?.bookId, bookId: book?.bookId,
character: updatedCharacter, character: updatedCharacter,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!characterId) { if (!characterId) {
errorMessage(t("characterComponent.errorAddCharacter")); errorMessage(t("characterComponent.errorAddCharacter"));
return; return;
@@ -130,9 +145,16 @@ export function CharacterComponent(props: any, ref: any) {
async function updateCharacter(updatedCharacter: CharacterProps,): Promise<void> { async function updateCharacter(updatedCharacter: CharacterProps,): Promise<void> {
try { try {
const response: boolean = await System.authPostToServer<boolean>(`character/update`, { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:character:update', {
character: updatedCharacter,
});
} else {
response = await System.authPostToServer<boolean>(`character/update`, {
character: updatedCharacter, character: updatedCharacter,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!response) { if (!response) {
errorMessage(t("characterComponent.errorUpdateCharacter")); errorMessage(t("characterComponent.errorUpdateCharacter"));
return; return;
@@ -175,11 +197,20 @@ export function CharacterComponent(props: any, ref: any) {
setSelectedCharacter({...selectedCharacter, [section]: updatedSection}); setSelectedCharacter({...selectedCharacter, [section]: updatedSection});
} else { } else {
try { try {
const attributeId: string = await System.authPostToServer<string>(`character/attribute/add`, { let attributeId: string;
if (isCurrentlyOffline()) {
attributeId = await window.electron.invoke<string>('db:character:attribute:add', {
characterId: selectedCharacter.id,
type: section,
name: value.name,
});
} else {
attributeId = await System.authPostToServer<string>(`character/attribute/add`, {
characterId: selectedCharacter.id, characterId: selectedCharacter.id,
type: section, type: section,
name: value.name, name: value.name,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!attributeId) { if (!attributeId) {
errorMessage(t("characterComponent.errorAddAttribute")); errorMessage(t("characterComponent.errorAddAttribute"));
return; return;
@@ -214,9 +245,16 @@ export function CharacterComponent(props: any, ref: any) {
setSelectedCharacter({...selectedCharacter, [section]: updatedSection}); setSelectedCharacter({...selectedCharacter, [section]: updatedSection});
} else { } else {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>(`character/attribute/delete`, { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:character:attribute:delete', {
attributeId: attrId,
});
} else {
response = await System.authDeleteToServer<boolean>(`character/attribute/delete`, {
attributeId: attrId, attributeId: attrId,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!response) { if (!response) {
errorMessage(t("characterComponent.errorRemoveAttribute")); errorMessage(t("characterComponent.errorRemoveAttribute"));
return; return;

View File

@@ -29,6 +29,7 @@ import {Dispatch, SetStateAction, useContext, useEffect} from "react";
import CharacterSectionElement from "@/components/book/settings/characters/CharacterSectionElement"; import CharacterSectionElement from "@/components/book/settings/characters/CharacterSectionElement";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext} from "@/context/LangContext"; import {LangContext} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface CharacterDetailProps { interface CharacterDetailProps {
selectedCharacter: CharacterProps | null; selectedCharacter: CharacterProps | null;
@@ -55,6 +56,7 @@ export default function CharacterDetail(
) { ) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext(LangContext); const {lang} = useContext(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {errorMessage} = useContext(AlertContext); const {errorMessage} = useContext(AlertContext);
@@ -66,9 +68,16 @@ export default function CharacterDetail(
async function getAttributes(): Promise<void> { async function getAttributes(): Promise<void> {
try { try {
const response: CharacterAttribute = await System.authGetQueryToServer<CharacterAttribute>(`character/attribute`, session.accessToken, lang, { let response: CharacterAttribute;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<CharacterAttribute>('db:character:attributes', {
characterId: selectedCharacter?.id, characterId: selectedCharacter?.id,
}); });
} else {
response = await System.authGetQueryToServer<CharacterAttribute>(`character/attribute`, session.accessToken, lang, {
characterId: selectedCharacter?.id,
});
}
if (response) { if (response) {
setSelectedCharacter({ setSelectedCharacter({
id: selectedCharacter?.id ?? '', id: selectedCharacter?.id ?? '',

View File

@@ -21,10 +21,12 @@ import {
} from "@/lib/models/Story"; } from "@/lib/models/Story";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext} from "@/context/LangContext"; import {LangContext} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
function GuideLineSetting(props: any, ref: any) { function GuideLineSetting(props: any, ref: any) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext(LangContext); const {lang} = useContext(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const userToken: string = session?.accessToken ? session?.accessToken : ''; const userToken: string = session?.accessToken ? session?.accessToken : '';
@@ -75,7 +77,12 @@ function GuideLineSetting(props: any, ref: any) {
async function getAIGuideLine(): Promise<void> { async function getAIGuideLine(): Promise<void> {
try { try {
const response: GuideLineAI = await System.authGetQueryToServer<GuideLineAI>(`book/ai/guideline`, userToken, lang, {id: bookId}); let response: GuideLineAI;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<GuideLineAI>('db:book:guideline:ai:get', {id: bookId});
} else {
response = await System.authGetQueryToServer<GuideLineAI>(`book/ai/guideline`, userToken, lang, {id: bookId});
}
if (response) { if (response) {
setPlotSummary(response.globalResume); setPlotSummary(response.globalResume);
setVerbTense(response.verbeTense?.toString() || ''); setVerbTense(response.verbeTense?.toString() || '');
@@ -96,13 +103,17 @@ function GuideLineSetting(props: any, ref: any) {
async function getGuideLine(): Promise<void> { async function getGuideLine(): Promise<void> {
try { try {
const response: GuideLine = let response: GuideLine;
await System.authGetQueryToServer<GuideLine>( if (isCurrentlyOffline()) {
response = await window.electron.invoke<GuideLine>('db:book:guideline:get', {id: bookId});
} else {
response = await System.authGetQueryToServer<GuideLine>(
`book/guide-line`, `book/guide-line`,
userToken, userToken,
lang, lang,
{id: bookId}, {id: bookId},
); );
}
if (response) { if (response) {
setTone(response.tone); setTone(response.tone);
setAtmosphere(response.atmosphere); setAtmosphere(response.atmosphere);
@@ -126,10 +137,8 @@ function GuideLineSetting(props: any, ref: any) {
async function savePersonal(): Promise<void> { async function savePersonal(): Promise<void> {
try { try {
const response: boolean = let response: boolean;
await System.authPostToServer<boolean>( const guidelineData = {
'book/guide-line',
{
bookId: bookId, bookId: bookId,
tone: tone, tone: tone,
atmosphere: atmosphere, atmosphere: atmosphere,
@@ -141,10 +150,17 @@ function GuideLineSetting(props: any, ref: any) {
pacing: pacing, pacing: pacing,
intendedAudience: intendedAudience, intendedAudience: intendedAudience,
keyMessages: keyMessages, keyMessages: keyMessages,
}, };
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:guideline:update', guidelineData);
} else {
response = await System.authPostToServer<boolean>(
'book/guide-line',
guidelineData,
userToken, userToken,
lang, lang,
); );
}
if (!response) { if (!response) {
errorMessage(t("guideLineSetting.saveError")); errorMessage(t("guideLineSetting.saveError"));
return; return;

View File

@@ -11,6 +11,7 @@ import TextInput from '@/components/form/TextInput';
import TexteAreaInput from "@/components/form/TexteAreaInput"; import TexteAreaInput from "@/components/form/TexteAreaInput";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface SubElement { interface SubElement {
id: string; id: string;
@@ -34,6 +35,7 @@ interface LocationProps {
export function LocationComponent(props: any, ref: any) { export function LocationComponent(props: any, ref: any) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext); const {lang} = useContext<LangContextProps>(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {successMessage, errorMessage} = useContext(AlertContext); const {successMessage, errorMessage} = useContext(AlertContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
@@ -58,9 +60,14 @@ export function LocationComponent(props: any, ref: any) {
async function getAllLocations(): Promise<void> { async function getAllLocations(): Promise<void> {
try { try {
const response: LocationProps[] = await System.authGetQueryToServer<LocationProps[]>(`location/all`, token, lang, { let response: LocationProps[];
if (isCurrentlyOffline()) {
response = await window.electron.invoke<LocationProps[]>('db:location:all', {bookid: bookId});
} else {
response = await System.authGetQueryToServer<LocationProps[]>(`location/all`, token, lang, {
bookid: bookId, bookid: bookId,
}); });
}
if (response && response.length > 0) { if (response && response.length > 0) {
setSections(response); setSections(response);
} }
@@ -79,10 +86,18 @@ export function LocationComponent(props: any, ref: any) {
return return
} }
try { try {
const sectionId: string = await System.authPostToServer<string>(`location/section/add`, { let sectionId: string;
if (isCurrentlyOffline()) {
sectionId = await window.electron.invoke<string>('db:location:section:add', {
bookId: bookId,
locationName: newSectionName,
});
} else {
sectionId = await System.authPostToServer<string>(`location/section/add`, {
bookId: bookId, bookId: bookId,
locationName: newSectionName, locationName: newSectionName,
}, token, lang); }, token, lang);
}
if (!sectionId) { if (!sectionId) {
errorMessage(t('locationComponent.errorUnknownAddSection')); errorMessage(t('locationComponent.errorUnknownAddSection'));
return; return;
@@ -109,12 +124,21 @@ export function LocationComponent(props: any, ref: any) {
return return
} }
try { try {
const elementId: string = await System.authPostToServer<string>(`location/element/add`, { let elementId: string;
if (isCurrentlyOffline()) {
elementId = await window.electron.invoke<string>('db:location:element:add', {
bookId: bookId,
locationId: sectionId,
elementName: newElementNames[sectionId],
});
} else {
elementId = await System.authPostToServer<string>(`location/element/add`, {
bookId: bookId, bookId: bookId,
locationId: sectionId, locationId: sectionId,
elementName: newElementNames[sectionId], elementName: newElementNames[sectionId],
}, },
token, lang); token, lang);
}
if (!elementId) { if (!elementId) {
errorMessage(t('locationComponent.errorUnknownAddElement')); errorMessage(t('locationComponent.errorUnknownAddElement'));
return; return;
@@ -167,10 +191,18 @@ export function LocationComponent(props: any, ref: any) {
(section: LocationProps): boolean => section.id === sectionId, (section: LocationProps): boolean => section.id === sectionId,
); );
try { try {
const subElementId: string = await System.authPostToServer<string>(`location/sub-element/add`, { let subElementId: string;
if (isCurrentlyOffline()) {
subElementId = await window.electron.invoke<string>('db:location:subelement:add', {
elementId: sections[sectionIndex].elements[elementIndex].id,
subElementName: newSubElementNames[elementIndex],
});
} else {
subElementId = await System.authPostToServer<string>(`location/sub-element/add`, {
elementId: sections[sectionIndex].elements[elementIndex].id, elementId: sections[sectionIndex].elements[elementIndex].id,
subElementName: newSubElementNames[elementIndex], subElementName: newSubElementNames[elementIndex],
}, token, lang); }, token, lang);
}
if (!subElementId) { if (!subElementId) {
errorMessage(t('locationComponent.errorUnknownAddSubElement')); errorMessage(t('locationComponent.errorUnknownAddSubElement'));
return; return;
@@ -214,10 +246,18 @@ export function LocationComponent(props: any, ref: any) {
elementIndex: number, elementIndex: number,
): Promise<void> { ): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>(`location/element/delete`, { let response: boolean;
elementId: sections.find((section: LocationProps): boolean => section.id === sectionId) const elementId = sections.find((section: LocationProps): boolean => section.id === sectionId)
?.elements[elementIndex].id, ?.elements[elementIndex].id;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:location:element:delete', {
elementId: elementId,
});
} else {
response = await System.authDeleteToServer<boolean>(`location/element/delete`, {
elementId: elementId,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('locationComponent.errorUnknownDeleteElement')); errorMessage(t('locationComponent.errorUnknownDeleteElement'));
return; return;
@@ -241,9 +281,17 @@ export function LocationComponent(props: any, ref: any) {
subElementIndex: number, subElementIndex: number,
): Promise<void> { ): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>(`location/sub-element/delete`, { let response: boolean;
subElementId: sections.find((section: LocationProps): boolean => section.id === sectionId)?.elements[elementIndex].subElements[subElementIndex].id, const subElementId = sections.find((section: LocationProps): boolean => section.id === sectionId)?.elements[elementIndex].subElements[subElementIndex].id;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:location:subelement:delete', {
subElementId: subElementId,
});
} else {
response = await System.authDeleteToServer<boolean>(`location/sub-element/delete`, {
subElementId: subElementId,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('locationComponent.errorUnknownDeleteSubElement')); errorMessage(t('locationComponent.errorUnknownDeleteSubElement'));
return; return;
@@ -263,9 +311,16 @@ export function LocationComponent(props: any, ref: any) {
async function handleRemoveSection(sectionId: string): Promise<void> { async function handleRemoveSection(sectionId: string): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>(`location/delete`, { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:location:delete', {
locationId: sectionId,
});
} else {
response = await System.authDeleteToServer<boolean>(`location/delete`, {
locationId: sectionId, locationId: sectionId,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('locationComponent.errorUnknownDeleteSection')); errorMessage(t('locationComponent.errorUnknownDeleteSection'));
return; return;
@@ -283,9 +338,16 @@ export function LocationComponent(props: any, ref: any) {
async function handleSave(): Promise<void> { async function handleSave(): Promise<void> {
try { try {
const response: boolean = await System.authPostToServer<boolean>(`location/update`, { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:location:update', {
locations: sections,
});
} else {
response = await System.authPostToServer<boolean>(`location/update`, {
locations: sections, locations: sections,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('locationComponent.errorUnknownSave')); errorMessage(t('locationComponent.errorUnknownSave'));
return; return;

View File

@@ -20,6 +20,7 @@ import ActIncidents from '@/components/book/settings/story/act/ActIncidents';
import ActPlotPoints from '@/components/book/settings/story/act/ActPlotPoints'; import ActPlotPoints from '@/components/book/settings/story/act/ActPlotPoints';
import {useTranslations} from 'next-intl'; import {useTranslations} from 'next-intl';
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface ActProps { interface ActProps {
acts: ActType[]; acts: ActType[];
@@ -30,6 +31,7 @@ interface ActProps {
export default function Act({acts, setActs, mainChapters}: ActProps) { export default function Act({acts, setActs, mainChapters}: ActProps) {
const t = useTranslations('actComponent'); const t = useTranslations('actComponent');
const {lang} = useContext<LangContextProps>(LangContext); const {lang} = useContext<LangContextProps>(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {errorMessage, successMessage} = useContext(AlertContext); const {errorMessage, successMessage} = useContext(AlertContext);
@@ -71,11 +73,18 @@ export default function Act({acts, setActs, mainChapters}: ActProps) {
if (newIncidentTitle.trim() === '') return; if (newIncidentTitle.trim() === '') return;
try { try {
const incidentId: string = let incidentId: string;
await System.authPostToServer<string>('book/incident/new', { if (isCurrentlyOffline()) {
incidentId = await window.electron.invoke<string>('db:book:incident:add', {
bookId,
name: newIncidentTitle,
});
} else {
incidentId = await System.authPostToServer<string>('book/incident/new', {
bookId, bookId,
name: newIncidentTitle, name: newIncidentTitle,
}, token, lang); }, token, lang);
}
if (!incidentId) { if (!incidentId) {
errorMessage(t('errorAddIncident')); errorMessage(t('errorAddIncident'));
return; return;
@@ -109,10 +118,18 @@ export default function Act({acts, setActs, mainChapters}: ActProps) {
async function deleteIncident(actId: number, incidentId: string): Promise<void> { async function deleteIncident(actId: number, incidentId: string): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>('book/incident/remove', { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:incident:remove', {
bookId,
incidentId,
});
} else {
response = await System.authDeleteToServer<boolean>('book/incident/remove', {
bookId, bookId,
incidentId, incidentId,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('errorDeleteIncident')); errorMessage(t('errorDeleteIncident'));
return; return;
@@ -141,11 +158,20 @@ export default function Act({acts, setActs, mainChapters}: ActProps) {
async function addPlotPoint(actId: number): Promise<void> { async function addPlotPoint(actId: number): Promise<void> {
if (newPlotPointTitle.trim() === '') return; if (newPlotPointTitle.trim() === '') return;
try { try {
const plotId: string = await System.authPostToServer<string>('book/plot/new', { let plotId: string;
if (isCurrentlyOffline()) {
plotId = await window.electron.invoke<string>('db:book:plot:add', {
bookId,
name: newPlotPointTitle,
incidentId: selectedIncidentId,
});
} else {
plotId = await System.authPostToServer<string>('book/plot/new', {
bookId, bookId,
name: newPlotPointTitle, name: newPlotPointTitle,
incidentId: selectedIncidentId, incidentId: selectedIncidentId,
}, token, lang); }, token, lang);
}
if (!plotId) { if (!plotId) {
errorMessage(t('errorAddPlotPoint')); errorMessage(t('errorAddPlotPoint'));
return; return;
@@ -180,9 +206,16 @@ export default function Act({acts, setActs, mainChapters}: ActProps) {
async function deletePlotPoint(actId: number, plotPointId: string): Promise<void> { async function deletePlotPoint(actId: number, plotPointId: string): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>('book/plot/remove', { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:plot:remove', {
plotId: plotPointId,
});
} else {
response = await System.authDeleteToServer<boolean>('book/plot/remove', {
plotId: plotPointId, plotId: plotPointId,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('errorDeletePlotPoint')); errorMessage(t('errorDeletePlotPoint'));
return; return;
@@ -220,14 +253,19 @@ export default function Act({acts, setActs, mainChapters}: ActProps) {
return; return;
} }
try { try {
const linkId: string = let linkId: string;
await System.authPostToServer<string>('chapter/resume/add', { const linkData = {
bookId, bookId,
chapterId: chapterId, chapterId: chapterId,
actId: actId, actId: actId,
plotId: destination === 'plotPoint' ? itemId : null, plotId: destination === 'plotPoint' ? itemId : null,
incidentId: destination === 'incident' ? itemId : null, incidentId: destination === 'incident' ? itemId : null,
}, token, lang); };
if (isCurrentlyOffline()) {
linkId = await window.electron.invoke<string>('db:chapter:information:add', linkData);
} else {
linkId = await System.authPostToServer<string>('chapter/resume/add', linkData, token, lang);
}
if (!linkId) { if (!linkId) {
errorMessage(t('errorLinkChapter')); errorMessage(t('errorLinkChapter'));
return; return;
@@ -302,9 +340,16 @@ export default function Act({acts, setActs, mainChapters}: ActProps) {
itemId?: string, itemId?: string,
): Promise<void> { ): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>('chapter/resume/remove', { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:chapter:information:remove', {
chapterInfoId,
});
} else {
response = await System.authDeleteToServer<boolean>('chapter/resume/remove', {
chapterInfoId, chapterInfoId,
}, token, lang); }, token, lang);
}
if (!response) { if (!response) {
errorMessage(t('errorUnlinkChapter')); errorMessage(t('errorUnlinkChapter'));
return; return;

View File

@@ -9,6 +9,7 @@ import {AlertContext} from '@/context/AlertContext';
import CollapsableArea from "@/components/CollapsableArea"; import CollapsableArea from "@/components/CollapsableArea";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface IssuesProps { interface IssuesProps {
issues: Issue[]; issues: Issue[];
@@ -18,6 +19,7 @@ interface IssuesProps {
export default function Issues({issues, setIssues}: IssuesProps) { export default function Issues({issues, setIssues}: IssuesProps) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext); const {lang} = useContext<LangContextProps>(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {errorMessage} = useContext(AlertContext); const {errorMessage} = useContext(AlertContext);
@@ -33,10 +35,18 @@ export default function Issues({issues, setIssues}: IssuesProps) {
return; return;
} }
try { try {
const issueId: string = await System.authPostToServer<string>('book/issue/add', { let issueId: string;
if (isCurrentlyOffline()) {
issueId = await window.electron.invoke<string>('db:book:issue:add', {
bookId,
name: newIssueName,
});
} else {
issueId = await System.authPostToServer<string>('book/issue/add', {
bookId, bookId,
name: newIssueName, name: newIssueName,
}, token, lang); }, token, lang);
}
if (!issueId) { if (!issueId) {
errorMessage(t("issues.errorAdd")); errorMessage(t("issues.errorAdd"));
return; return;
@@ -64,7 +74,14 @@ export default function Issues({issues, setIssues}: IssuesProps) {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>( let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:issue:remove', {
bookId,
issueId,
});
} else {
response = await System.authDeleteToServer<boolean>(
'book/issue/remove', 'book/issue/remove',
{ {
bookId, bookId,
@@ -73,6 +90,7 @@ export default function Issues({issues, setIssues}: IssuesProps) {
token, token,
lang lang
); );
}
if (response) { if (response) {
const updatedIssues: Issue[] = issues.filter((issue: Issue): boolean => issue.id !== issueId,); const updatedIssues: Issue[] = issues.filter((issue: Issue): boolean => issue.id !== issueId,);
setIssues(updatedIssues); setIssues(updatedIssues);

View File

@@ -12,6 +12,7 @@ import Issues from "@/components/book/settings/story/Issue";
import Act from "@/components/book/settings/story/Act"; import Act from "@/components/book/settings/story/Act";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
export const StoryContext = createContext<{ export const StoryContext = createContext<{
acts: ActType[]; acts: ActType[];
@@ -41,6 +42,7 @@ interface StoryFetchData {
export function Story(props: any, ref: any) { export function Story(props: any, ref: any) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext); const {lang} = useContext<LangContextProps>(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
const bookId: string = book?.bookId ? book.bookId.toString() : ''; const bookId: string = book?.bookId ? book.bookId.toString() : '';
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
@@ -68,9 +70,14 @@ export function Story(props: any, ref: any) {
async function getStoryData(): Promise<void> { async function getStoryData(): Promise<void> {
try { try {
const response: StoryFetchData = await System.authGetQueryToServer<StoryFetchData>(`book/story`, userToken, lang, { let response: StoryFetchData;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<StoryFetchData>('db:book:story:get', {bookid: bookId});
} else {
response = await System.authGetQueryToServer<StoryFetchData>(`book/story`, userToken, lang, {
bookid: bookId, bookid: bookId,
}); });
}
if (response) { if (response) {
setActs(response.acts); setActs(response.acts);
setMainChapters(response.mainChapter); setMainChapters(response.mainChapter);
@@ -119,13 +126,18 @@ export function Story(props: any, ref: any) {
async function handleSave(): Promise<void> { async function handleSave(): Promise<void> {
try { try {
const response: boolean = let response: boolean;
await System.authPostToServer<boolean>('book/story', { const storyData = {
bookId, bookId,
acts, acts,
mainChapters, mainChapters,
issues, issues,
}, userToken, lang); };
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:story:update', storyData);
} else {
response = await System.authPostToServer<boolean>('book/story', storyData, userToken, lang);
}
if (!response) { if (!response) {
errorMessage(t("story.errorSave")) errorMessage(t("story.errorSave"))
} }

View File

@@ -11,6 +11,7 @@ import System from "@/lib/models/System";
import InputField from "@/components/form/InputField"; import InputField from "@/components/form/InputField";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
interface WorldElementInputProps { interface WorldElementInputProps {
sectionLabel: string; sectionLabel: string;
@@ -20,6 +21,7 @@ interface WorldElementInputProps {
export default function WorldElementComponent({sectionLabel, sectionType}: WorldElementInputProps) { export default function WorldElementComponent({sectionLabel, sectionType}: WorldElementInputProps) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext); const {lang} = useContext<LangContextProps>(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {worlds, setWorlds, selectedWorldIndex} = useContext(WorldContext); const {worlds, setWorlds, selectedWorldIndex} = useContext(WorldContext);
const {errorMessage, successMessage} = useContext(AlertContext); const {errorMessage, successMessage} = useContext(AlertContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
@@ -31,9 +33,17 @@ export default function WorldElementComponent({sectionLabel, sectionType}: World
index: number, index: number,
): Promise<void> { ): Promise<void> {
try { try {
const response: boolean = await System.authDeleteToServer<boolean>('book/world/element/delete', { let response: boolean;
elementId: (worlds[selectedWorldIndex][section] as WorldElement[])[index].id, const elementId = (worlds[selectedWorldIndex][section] as WorldElement[])[index].id;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:world:element:remove', {
elementId: elementId,
});
} else {
response = await System.authDeleteToServer<boolean>('book/world/element/delete', {
elementId: elementId,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!response) { if (!response) {
errorMessage(t("worldSetting.unknownError")) errorMessage(t("worldSetting.unknownError"))
} }
@@ -58,11 +68,20 @@ export default function WorldElementComponent({sectionLabel, sectionType}: World
return; return;
} }
try { try {
const elementId: string = await System.authPostToServer('book/world/element/add', { let elementId: string;
if (isCurrentlyOffline()) {
elementId = await window.electron.invoke<string>('db:book:world:element:add', {
elementType: section,
worldId: worlds[selectedWorldIndex].id,
elementName: newElementName,
});
} else {
elementId = await System.authPostToServer('book/world/element/add', {
elementType: section, elementType: section,
worldId: worlds[selectedWorldIndex].id, worldId: worlds[selectedWorldIndex].id,
elementName: newElementName, elementName: newElementName,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!elementId) { if (!elementId) {
errorMessage(t("worldSetting.unknownError")) errorMessage(t("worldSetting.unknownError"))
return; return;

View File

@@ -16,6 +16,7 @@ import WorldElementComponent from './WorldElement';
import SelectBox from "@/components/form/SelectBox"; import SelectBox from "@/components/form/SelectBox";
import {useTranslations} from "next-intl"; import {useTranslations} from "next-intl";
import {LangContext, LangContextProps} from "@/context/LangContext"; import {LangContext, LangContextProps} from "@/context/LangContext";
import OfflineContext, {OfflineContextType} from "@/context/OfflineContext";
export interface ElementSection { export interface ElementSection {
title: string; title: string;
@@ -26,6 +27,7 @@ export interface ElementSection {
export function WorldSetting(props: any, ref: any) { export function WorldSetting(props: any, ref: any) {
const t = useTranslations(); const t = useTranslations();
const {lang} = useContext<LangContextProps>(LangContext); const {lang} = useContext<LangContextProps>(LangContext);
const {isCurrentlyOffline} = useContext<OfflineContextType>(OfflineContext);
const {errorMessage, successMessage} = useContext(AlertContext); const {errorMessage, successMessage} = useContext(AlertContext);
const {session} = useContext(SessionContext); const {session} = useContext(SessionContext);
const {book} = useContext(BookContext); const {book} = useContext(BookContext);
@@ -49,9 +51,14 @@ export function WorldSetting(props: any, ref: any) {
async function getWorlds() { async function getWorlds() {
try { try {
const response: WorldProps[] = await System.authGetQueryToServer<WorldProps[]>(`book/worlds`, session.accessToken, lang, { let response: WorldProps[];
if (isCurrentlyOffline()) {
response = await window.electron.invoke<WorldProps[]>('db:book:worlds:get', {bookid: bookId});
} else {
response = await System.authGetQueryToServer<WorldProps[]>(`book/worlds`, session.accessToken, lang, {
bookid: bookId, bookid: bookId,
}); });
}
if (response) { if (response) {
setWorlds(response); setWorlds(response);
const formattedWorlds: SelectBoxProps[] = response.map( const formattedWorlds: SelectBoxProps[] = response.map(
@@ -77,10 +84,18 @@ export function WorldSetting(props: any, ref: any) {
return; return;
} }
try { try {
const worldId: string = await System.authPostToServer<string>('book/world/add', { let worldId: string;
if (isCurrentlyOffline()) {
worldId = await window.electron.invoke<string>('db:book:world:add', {
worldName: newWorldName,
bookId: bookId,
});
} else {
worldId = await System.authPostToServer<string>('book/world/add', {
worldName: newWorldName, worldName: newWorldName,
bookId: bookId, bookId: bookId,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!worldId) { if (!worldId) {
errorMessage(t("worldSetting.addWorldError")); errorMessage(t("worldSetting.addWorldError"));
return; return;
@@ -125,10 +140,18 @@ export function WorldSetting(props: any, ref: any) {
async function handleUpdateWorld(): Promise<void> { async function handleUpdateWorld(): Promise<void> {
try { try {
const response: boolean = await System.authPutToServer<boolean>('book/world/update', { let response: boolean;
if (isCurrentlyOffline()) {
response = await window.electron.invoke<boolean>('db:book:world:update', {
world: worlds[selectedWorldIndex],
bookId: bookId,
});
} else {
response = await System.authPutToServer<boolean>('book/world/update', {
world: worlds[selectedWorldIndex], world: worlds[selectedWorldIndex],
bookId: bookId, bookId: bookId,
}, session.accessToken, lang); }, session.accessToken, lang);
}
if (!response) { if (!response) {
errorMessage(t("worldSetting.updateWorldError")); errorMessage(t("worldSetting.updateWorldError"));
return; return;

View File

@@ -111,10 +111,13 @@ ipcMain.handle('db:book:updateBasicInformation', createHandler<UpdateBookBasicDa
); );
// GET /book/guide-line - Get guideline // GET /book/guide-line - Get guideline
interface GetGuidelineData {
id: string;
}
ipcMain.handle( ipcMain.handle(
'db:book:guideline:get', 'db:book:guideline:get',
createHandler<string, GuideLine | null>(async function(userId: string, bookId: string, lang: 'fr' | 'en') { createHandler<GetGuidelineData, GuideLine | null>(async function(userId: string, data: GetGuidelineData, lang: 'fr' | 'en') {
return await Book.getGuideLine(userId, bookId, lang); return await Book.getGuideLine(userId, data.id, lang);
} }
) )
); );
@@ -142,10 +145,13 @@ ipcMain.handle('db:book:guideline:update', createHandler<UpdateGuideLineData, bo
); );
// GET /book/story - Get story data (acts + issues) // GET /book/story - Get story data (acts + issues)
ipcMain.handle('db:book:story:get', createHandler<string, StoryData>( interface GetStoryData {
async function(userId: string, bookId: string, lang: 'fr' | 'en'):Promise<StoryData> { bookid: string;
const acts:Act[] = await Book.getActsData(userId, bookId, lang); }
const issues:Issue[] = await Book.getIssuesFromBook(userId, bookId, lang); ipcMain.handle('db:book:story:get', createHandler<GetStoryData, StoryData>(
async function(userId: string, data: GetStoryData, lang: 'fr' | 'en'):Promise<StoryData> {
const acts:Act[] = await Book.getActsData(userId, data.bookid, lang);
const issues:Issue[] = await Book.getIssuesFromBook(userId, data.bookid, lang);
return { return {
acts, acts,
issues issues
@@ -220,11 +226,14 @@ ipcMain.handle('db:book:plot:add', createHandler<AddPlotPointData, string>(
); );
// DELETE /book/plot/remove - Remove plot point // DELETE /book/plot/remove - Remove plot point
interface RemovePlotData {
plotId: string;
}
ipcMain.handle( ipcMain.handle(
'db:book:plot:remove', 'db:book:plot:remove',
createHandler<string, boolean>( createHandler<RemovePlotData, boolean>(
function(userId: string, plotPointId: string, lang: 'fr' | 'en') { function(userId: string, data: RemovePlotData, lang: 'fr' | 'en') {
return Book.removePlotPoint(userId, plotPointId, lang); return Book.removePlotPoint(userId, data.plotId, lang);
} }
) )
); );
@@ -238,17 +247,24 @@ ipcMain.handle('db:book:issue:add', createHandler<AddIssueData, string>(
); );
// DELETE /book/issue/remove - Remove issue // DELETE /book/issue/remove - Remove issue
ipcMain.handle('db:book:issue:remove', createHandler<string, boolean>( interface RemoveIssueData {
function(userId: string, issueId: string, lang: 'fr' | 'en') { bookId: string;
return Book.removeIssue(userId, issueId, lang); issueId: string;
}
ipcMain.handle('db:book:issue:remove', createHandler<RemoveIssueData, boolean>(
function(userId: string, data: RemoveIssueData, lang: 'fr' | 'en') {
return Book.removeIssue(userId, data.issueId, lang);
} }
) )
); );
// GET /book/worlds - Get worlds for book // GET /book/worlds - Get worlds for book
ipcMain.handle('db:book:worlds:get', createHandler<string, WorldProps[]>( interface GetWorldsData {
function(userId: string, bookId: string, lang: 'fr' | 'en') { bookid: string;
return Book.getWorlds(userId, bookId, lang); }
ipcMain.handle('db:book:worlds:get', createHandler<GetWorldsData, WorldProps[]>(
function(userId: string, data: GetWorldsData, lang: 'fr' | 'en') {
return Book.getWorlds(userId, data.bookid, lang);
} }
) )
); );
@@ -275,25 +291,34 @@ ipcMain.handle('db:book:world:element:add', createHandler<AddWorldElementData, s
) )
); );
// DELETE /book/world/element/delete - Remove element from world // DELETE /book/world/element/delete - Remove element from world
ipcMain.handle('db:book:world:element:remove', createHandler<string, boolean>( interface RemoveWorldElementData {
function(userId: string, elementId: string, lang: 'fr' | 'en') { elementId: string;
return Book.removeElementFromWorld(userId, elementId, lang); }
ipcMain.handle('db:book:world:element:remove', createHandler<RemoveWorldElementData, boolean>(
function(userId: string, data: RemoveWorldElementData, lang: 'fr' | 'en') {
return Book.removeElementFromWorld(userId, data.elementId, lang);
} }
) )
); );
// DELETE /book/delete - Delete book // DELETE /book/delete - Delete book
ipcMain.handle('db:book:delete', createHandler<string, boolean>( interface DeleteBookData {
function(userId: string, bookId: string, lang: 'fr' | 'en') { id: string;
return Book.removeBook(userId, bookId, lang); }
ipcMain.handle('db:book:delete', createHandler<DeleteBookData, boolean>(
function(userId: string, data: DeleteBookData, lang: 'fr' | 'en') {
return Book.removeBook(userId, data.id, lang);
} }
) )
); );
// GET /book/ai/guideline - Get AI guideline // GET /book/ai/guideline - Get AI guideline
ipcMain.handle('db:book:guideline:ai:get', createHandler<string, GuideLineAI>( interface GetAIGuidelineData {
function(userId: string, bookId: string, lang: 'fr' | 'en') { id: string;
return Book.getGuideLineAI(userId, bookId, lang); }
ipcMain.handle('db:book:guideline:ai:get', createHandler<GetAIGuidelineData, GuideLineAI>(
function(userId: string, data: GetAIGuidelineData, lang: 'fr' | 'en') {
return Book.getGuideLineAI(userId, data.id, lang);
} }
) )
); );

View File

@@ -148,9 +148,12 @@ ipcMain.handle('db:chapter:information:add', createHandler<AddChapterInformation
); );
// DELETE /chapter/resume/remove - Remove chapter information // DELETE /chapter/resume/remove - Remove chapter information
ipcMain.handle('db:chapter:information:remove', createHandler<string, boolean>( interface RemoveChapterInfoData {
function(userId: string, chapterInfoId: string, lang: 'fr' | 'en'): boolean { chapterInfoId: string;
return Chapter.removeChapterInformation(userId, chapterInfoId, lang); }
ipcMain.handle('db:chapter:information:remove', createHandler<RemoveChapterInfoData, boolean>(
function(userId: string, data: RemoveChapterInfoData, lang: 'fr' | 'en'): boolean {
return Chapter.removeChapterInformation(userId, data.chapterInfoId, lang);
} }
) )
); );

View File

@@ -15,17 +15,23 @@ interface AddAttributeData {
} }
// GET /character/list - Get character list // GET /character/list - Get character list
ipcMain.handle('db:character:list', createHandler<string, CharacterProps[]>( interface GetCharacterListData {
function(userId: string, bookId: string, lang: 'fr' | 'en'): CharacterProps[] { bookid: string;
return Character.getCharacterList(userId, bookId, lang); }
ipcMain.handle('db:character:list', createHandler<GetCharacterListData, CharacterProps[]>(
function(userId: string, data: GetCharacterListData, lang: 'fr' | 'en'): CharacterProps[] {
return Character.getCharacterList(userId, data.bookid, lang);
} }
) )
); );
// GET /character/attribute - Get character attributes // GET /character/attribute - Get character attributes
ipcMain.handle('db:character:attributes', createHandler<string, CharacterAttribute[]>( interface GetCharacterAttributesData {
function(userId: string, characterId: string, lang: 'fr' | 'en'): CharacterAttribute[] { characterId: string;
return Character.getAttributes(characterId, userId, lang); }
ipcMain.handle('db:character:attributes', createHandler<GetCharacterAttributesData, CharacterAttribute[]>(
function(userId: string, data: GetCharacterAttributesData, lang: 'fr' | 'en'): CharacterAttribute[] {
return Character.getAttributes(data.characterId, userId, lang);
} }
) )
); );
@@ -47,17 +53,23 @@ ipcMain.handle('db:character:attribute:add', createHandler<AddAttributeData, str
); );
// DELETE /character/attribute/delete - Delete character attribute // DELETE /character/attribute/delete - Delete character attribute
ipcMain.handle('db:character:attribute:delete', createHandler<string, boolean>( interface DeleteAttributeData {
function(userId: string, attributeId: string, lang: 'fr' | 'en'): boolean { attributeId: string;
return Character.deleteAttribute(userId, attributeId, lang); }
ipcMain.handle('db:character:attribute:delete', createHandler<DeleteAttributeData, boolean>(
function(userId: string, data: DeleteAttributeData, lang: 'fr' | 'en'): boolean {
return Character.deleteAttribute(userId, data.attributeId, lang);
} }
) )
); );
// POST /character/update - Update character // POST /character/update - Update character
ipcMain.handle('db:character:update', createHandler<CharacterPropsPost, boolean>( interface UpdateCharacterData {
function(userId: string, character: CharacterPropsPost, lang: 'fr' | 'en'): boolean { character: CharacterPropsPost;
return Character.updateCharacter(userId, character, lang); }
ipcMain.handle('db:character:update', createHandler<UpdateCharacterData, boolean>(
function(userId: string, data: UpdateCharacterData, lang: 'fr' | 'en'): boolean {
return Character.updateCharacter(userId, data.character, lang);
} }
) )
); );

View File

@@ -28,9 +28,12 @@ interface UpdateLocationData {
} }
// GET /location/all - Get all locations // GET /location/all - Get all locations
ipcMain.handle('db:location:all', createHandler<string, LocationProps[]>( interface GetAllLocationsData {
function(userId: string, bookId: string, lang: 'fr' | 'en'): LocationProps[] { bookid: string;
return Location.getAllLocations(userId, bookId, lang); }
ipcMain.handle('db:location:all', createHandler<GetAllLocationsData, LocationProps[]>(
function(userId: string, data: GetAllLocationsData, lang: 'fr' | 'en'): LocationProps[] {
return Location.getAllLocations(userId, data.bookid, lang);
} }
) )
); );
@@ -68,25 +71,34 @@ ipcMain.handle('db:location:update', createHandler<UpdateLocationData, UpdateLoc
); );
// DELETE /location/delete - Delete location section // DELETE /location/delete - Delete location section
ipcMain.handle('db:location:delete', createHandler<string, boolean>( interface DeleteLocationData {
function(userId: string, locationId: string, lang: 'fr' | 'en'): boolean { locationId: string;
return Location.deleteLocationSection(userId, locationId, lang); }
ipcMain.handle('db:location:delete', createHandler<DeleteLocationData, boolean>(
function(userId: string, data: DeleteLocationData, lang: 'fr' | 'en'): boolean {
return Location.deleteLocationSection(userId, data.locationId, lang);
} }
) )
); );
// DELETE /location/element/delete - Delete location element // DELETE /location/element/delete - Delete location element
ipcMain.handle('db:location:element:delete', createHandler<string, boolean>( interface DeleteLocationElementData {
function(userId: string, elementId: string, lang: 'fr' | 'en'): boolean { elementId: string;
return Location.deleteLocationElement(userId, elementId, lang); }
ipcMain.handle('db:location:element:delete', createHandler<DeleteLocationElementData, boolean>(
function(userId: string, data: DeleteLocationElementData, lang: 'fr' | 'en'): boolean {
return Location.deleteLocationElement(userId, data.elementId, lang);
} }
) )
); );
// DELETE /location/sub-element/delete - Delete location sub-element // DELETE /location/sub-element/delete - Delete location sub-element
ipcMain.handle('db:location:subelement:delete', createHandler<string, boolean>( interface DeleteLocationSubElementData {
function(userId: string, subElementId: string, lang: 'fr' | 'en'): boolean { subElementId: string;
return Location.deleteLocationSubElement(userId, subElementId, lang); }
ipcMain.handle('db:location:subelement:delete', createHandler<DeleteLocationSubElementData, boolean>(
function(userId: string, data: DeleteLocationSubElementData, lang: 'fr' | 'en'): boolean {
return Location.deleteLocationSubElement(userId, data.subElementId, lang);
} }
) )
); );