Skip to content

Commit

Permalink
Add category to stories
Browse files Browse the repository at this point in the history
  • Loading branch information
Franck ALARY committed Feb 23, 2024
1 parent 1b3ccb4 commit 009d98a
Show file tree
Hide file tree
Showing 16 changed files with 271 additions and 65 deletions.
11 changes: 6 additions & 5 deletions public/MainEvents/Helpers/StoriesFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,23 @@ const
}

const md = JSON.parse(fs.readFileSync(mdPath).toString('utf8'))
md.image = path.join(storiesPath, d, md.image)
md.audio = path.join(storiesPath, d, 'title.mp3')
md.path = path.join(storiesPath, d)
md.image = path.join(md.path, md.image)
md.audio = path.join(md.path, 'title.mp3')
return [...acc, md]
},
[]
)
.sort((a, b) => a.title.localeCompare(b.title))
},

deleteStories = (storiesPath, storiesUuid, onFinished) => {
if (!Array.isArray(storiesUuid)) {
deleteStories = (storiesPath, onFinished) => {
if (!Array.isArray(storiesPath)) {
return false
}
runProcess(
path.join('Stories', 'StoriesDelete.js'),
[storiesPath, ...storiesUuid],
storiesPath,
() => {},
() => {},
() => {},
Expand Down
43 changes: 30 additions & 13 deletions public/MainEvents/LocalStories.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as fs from 'fs'
import * as path from 'path'
import { getStoriesPath } from './Helpers/AppPaths.js'
import { deleteStories, readStories } from './Helpers/StoriesFiles.js'
import { generateDirNameStory } from './Processes/Helpers/Stories.js'

function mainEventLocalStoriesReader (mainWindow) {
ipcMain.on(
Expand All @@ -13,28 +14,44 @@ function mainEventLocalStoriesReader (mainWindow) {
)

ipcMain.on(
'local-story-update',
async (event, storyUuid, storyTitle) => {
if (
typeof storyUuid === 'string' && storyUuid !== '' &&
typeof storyTitle === 'string' && storyTitle !== ''
) {
'local-stories-update',
async (event, stories) => {
if (!Array.isArray(stories)) {
return
}
for (const story of stories) {
const
mdPath = path.join(getStoriesPath(storyUuid), 'metadata.json'),
mdPath = path.join(story.path, 'metadata.json'),
md = JSON.parse(fs.readFileSync(mdPath).toString('utf8'))
md.title = storyTitle
fs.writeFileSync(mdPath, JSON.stringify(md))
ipcMain.emit('local-stories-get')

fs.writeFileSync(
mdPath,
JSON.stringify(
Object.assign(
{
title: story.title,
uuid: story.uuid,
image: md.image,
},
story.category ? {category: story.category} : null,
story.age ? {age: story.age} : null,
)
)
)
const newStoryPath = getStoriesPath(generateDirNameStory(story.title, story.uuid, story.age, story.category))
if(story.path !== newStoryPath) {
fs.renameSync(story.path, newStoryPath)
}
}
ipcMain.emit('local-stories-get')
}
)

ipcMain.on(
'local-stories-delete',
async (event, storiesUuid) => {
async (event, stories) => {
deleteStories(
getStoriesPath(),
storiesUuid,
stories.map((s) => s.path),
() => ipcMain.emit('local-stories-get')
)
}
Expand Down
8 changes: 8 additions & 0 deletions public/MainEvents/Processes/Helpers/Stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { stringNormalizeFileName, stringSlugify } from '../../Helpers/Strings.js'

const
generateDirNameStory = (title, uuid, age, category) => {
return stringNormalizeFileName(category || '').substring(0, 32) + '_' + ((age || '') + '').substring(0, 32) + '_' + stringNormalizeFileName(title).substring(0, 32) + '_' + stringSlugify(uuid).substring(0, 36)
}

export { generateDirNameStory }
5 changes: 3 additions & 2 deletions public/MainEvents/Processes/Import/ConvertFolderFS.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createPathDirectories, rmDirectory } from '../../Helpers/Files.js'
import { getStoriesPath, initTmpPath } from '../Helpers/AppPaths.js'
import { convertStoryImages } from './Helpers/ImageFile.js'
import { stringSlugify } from '../../Helpers/Strings.js'
import { generateDirNameStory } from '../Helpers/Stories.js'

const
varsToTransitionNode = (transitionActionNodeIndexInLI, transitionNumberOfOptions, transitionSelectedOptionIndex, actionNodeKey) => {
Expand Down Expand Up @@ -61,9 +62,9 @@ function convertFolderFS (srcPath, storyName) {
renameAudio = (name) => findNewName(name, '.mp3', audiosNewNames),

tmpUuid = stringSlugify(path.basename(srcPath)),
uuid = tmpUuid.length > 48 ? tmpUuid.substring(0, 48) : tmpUuid,
uuid = tmpUuid.length > 36 ? tmpUuid.substring(0, 36) : tmpUuid,
title = storyName || uuid,
dstPath = getStoriesPath(uuid),
dstPath = getStoriesPath(generateDirNameStory(title, uuid)),
srcImagesPath = path.join(srcPath, 'rf'),
srcAudiosPath = path.join(srcPath, 'sf'),
dstImagesPath = path.join(dstPath, 'images'),
Expand Down
4 changes: 2 additions & 2 deletions public/MainEvents/Processes/Import/ConvertFolderSTUdio.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createPathDirectories, isDirectory, recursiveCountFiles, rmDirectory }
import { getStoriesPath } from '../Helpers/AppPaths.js'
import { convertStoryImages, isImageFile } from './Helpers/ImageFile.js'
import { convertAudios, isAudioFile } from './Helpers/AudioFile.js'
import { stringSlugify } from '../../Helpers/Strings.js'
import { generateDirNameStory } from '../Helpers/Stories.js'

function convertFolderSTUdio (srcPath, storyName) {
try {
Expand Down Expand Up @@ -50,7 +50,7 @@ function convertFolderSTUdio (srcPath, storyName) {

title = typeof studioData.title === 'string' ? studioData.title : (storyName || path.basename(srcPath)),

dstPath = getStoriesPath(stringSlugify(firstStageNode.uuid)),
dstPath = getStoriesPath(generateDirNameStory(title, firstStageNode.uuid)),
dstImagesPath = path.join(dstPath, 'images'),
dstAudiosPath = path.join(dstPath, 'audios'),

Expand Down
12 changes: 5 additions & 7 deletions public/MainEvents/Processes/Stories/StoriesDelete.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import * as path from 'path'

import { getProcessParams } from '../Helpers/ProcessParams.js'
import { rmDirectory } from '../../Helpers/Files.js'

function main (storiesPath, storiesUuids) {
function main (storiesPath) {
process.stdout.write('*initialize*0*1*')

let i = 0
for (const storyUuid of storiesUuids) {
process.stdout.write('*stories-deleting*' + (++i) + '*' + storiesUuids.length + '*')
rmDirectory(path.join(storiesPath, storyUuid))
for (const storyPath of storiesPath) {
process.stdout.write('*stories-deleting*' + (++i) + '*' + storiesPath.length + '*')
rmDirectory(storyPath)
}

process.stdout.write('success')
Expand All @@ -20,6 +18,6 @@ const _params_ = getProcessParams()
if (_params_.length === 0) {
process.stderr.write('no-file')
} else {
main(_params_.shift(), _params_)
main(_params_)
}

7 changes: 2 additions & 5 deletions public/MainEvents/Processes/Stories/StoryTransfer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@ import * as fs from 'fs'
import * as path from 'path'

import { getProcessParams } from '../Helpers/ProcessParams.js'
import { getStoriesPath } from '../Helpers/AppPaths.js'
import { createPathDirectories, isDirectory, rmDirectory } from '../../Helpers/Files.js'

function main (dstStoriesPath, storyUuid) {
function main (dstStoriesPath, srcStoryPath) {
process.stdout.write('*initialize*0*1*')

const
srcStoryPath = getStoriesPath(storyUuid),
dstStoryPath = path.join(dstStoriesPath, storyUuid)
const dstStoryPath = path.join(dstStoriesPath, path.basename(srcStoryPath))

if (!fs.existsSync(srcStoryPath)) {
process.stderr.write('story-not-found')
Expand Down
11 changes: 5 additions & 6 deletions public/MainEvents/USBStories.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,16 @@ function mainEventUsbStoriesReader (mainWindow) {

ipcMain.on(
'usb-stories-delete',
async (event, usb, storiesUuid) => {
async (event, usb, stories) => {
if (usb !== null) {
deleteStories(
getUsbStoriesPath(usb.drive),
storiesUuid,
stories.map((s) => s.path),
() => ipcMain.emit('usb-stories-get', event, usb)
)
}
}
)
const startTransfer = (usb, storiesPath, stories) => {
const startTransfer = (usb, dstPath, stories) => {
if (!stories.length) {
mainWindow.webContents.send('stories-transfer-task', '', '', 0, 0)
return ipcMain.emit('usb-stories-get', {}, usb)
Expand All @@ -39,15 +38,15 @@ function mainEventUsbStoriesReader (mainWindow) {

runProcess(
path.join('Stories', 'StoryTransfer.js'),
[storiesPath, story.uuid],
[dstPath, story.path],
() => {},
(message, current, total) => {
mainWindow.webContents.send('stories-transfer-task', story.title, message, current, total)
},
(error) => {
mainWindow.webContents.send('stories-transfer-error', story.title, error)
},
() => startTransfer(usb, storiesPath, stories)
() => startTransfer(usb, dstPath, stories)
)
}
ipcMain.on('stories-transfer', async (event, usb, stories) => startTransfer(usb, getUsbStoriesPath(usb.drive), stories))
Expand Down
8 changes: 5 additions & 3 deletions src/App/Modules/Synchronize/Music/MusicTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,15 @@ function MusicTable ({className, musics, selectedMusics, setSelectedMusics, onEd
const modal = <ModalMusicFormUpdate key={key}
music={music}
onValidate={(music) => {
setIsLoadingMusics(true)
onEdit(music)
setIsLoadingMusics(true)
setSelectedMusics([])
}}
onClose={() => rmModal(modal)}/>
return modal
})
},
[onEdit, addModal, rmModal]
[onEdit, setSelectedMusics, addModal, rmModal]
),

onCallbackEditSelected = useCallback(
Expand Down Expand Up @@ -105,12 +106,13 @@ function MusicTable ({className, musics, selectedMusics, setSelectedMusics, onEd
onConfirm={() => {
onDelete([music.id])
setIsLoadingMusics(true)
setSelectedMusics([])
}}
onClose={() => rmModal(modal)}/>
return modal
})
},
[onDelete, addModal, rmModal]
[onDelete, setSelectedMusics, addModal, rmModal]
),

onCallbackDeleteSelected = useCallback(
Expand Down
65 changes: 65 additions & 0 deletions src/App/Modules/Synchronize/Stories/ModalStoriesFormUpdate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { useRef } from 'react'
import { useLocale } from '../../../Components/Locale/LocaleHooks.js'
import ModalLayoutPadded from '../../../Components/Modal/ModalLayoutPadded.js'
import ButtonsContainer from '../../../Components/Buttons/ButtonsContainer.js'
import ButtonIconTextCheck from '../../../Components/Buttons/IconsTexts/ButtonIconTextCheck.js'
import InputText from '../../../Components/Form/Input/InputText.js'
import ModalTitle from '../../../Components/Modal/ModalTitle.js'
import ModalContent from '../../../Components/Modal/ModalContent.js'
import Form from '../../../Components/Form/Form.js'

function ModalStoryFormUpdate ({stories, onValidate, onClose}) {
const
{getLocale} = useLocale(),
inputAgeRef = useRef(),
inputCategoryRef = useRef()

return <ModalLayoutPadded isClosable={true}
onClose={onClose}>
<ModalTitle>{getLocale('stories-edit')} :</ModalTitle>
<Form>{
(validation) => {
return <>
<ModalContent>
<InputText label={getLocale('age')}
type="number"
step="1"
min="0"
max="99"
defaultValue={stories[0].age || 0}
required={false}
ref={inputAgeRef}/>
<InputText label={getLocale('category')}
defaultValue={stories[0].category || ''}
required={false}
ref={inputCategoryRef}/>
</ModalContent>
<ButtonsContainer>
<ButtonIconTextCheck text={getLocale('save')}
rounded={true}
onClick={() => {
validation(
[
inputAgeRef,
inputCategoryRef
],
(values) => {
onValidate(stories.map(
(story) => ({
...story,
age: values[0],
category: values[1]
})
))
onClose()
}
)
}}/>
</ButtonsContainer>
</>
}
}</Form>
</ModalLayoutPadded>
}

export default ModalStoryFormUpdate
32 changes: 28 additions & 4 deletions src/App/Modules/Synchronize/Stories/ModalStoryFormUpdate.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import Form from '../../../Components/Form/Form.js'
function ModalStoryFormUpdate ({story, onValidate, onClose}) {
const
{getLocale} = useLocale(),
inputRef = useRef()
inputTitleRef = useRef(),
inputAgeRef = useRef(),
inputCategoryRef = useRef()

return <ModalLayoutPadded isClosable={true}
onClose={onClose}>
<ModalTitle>{getLocale('story-edit')} :</ModalTitle>
Expand All @@ -22,16 +25,37 @@ function ModalStoryFormUpdate ({story, onValidate, onClose}) {
<InputText label={getLocale('title')}
defaultValue={story.title}
required={true}
ref={inputRef}/>
ref={inputTitleRef}/>
<InputText label={getLocale('age')}
type="number"
step="1"
min="0"
max="99"
defaultValue={story.age || 0}
required={false}
ref={inputAgeRef}/>
<InputText label={getLocale('category')}
defaultValue={story.category || ''}
required={false}
ref={inputCategoryRef}/>
</ModalContent>
<ButtonsContainer>
<ButtonIconTextCheck text={getLocale('save')}
rounded={true}
onClick={() => {
validation(
[inputRef],
[
inputTitleRef,
inputAgeRef,
inputCategoryRef
],
(values) => {
onValidate({...story, title: values[0]})
onValidate({
...story,
title: values[0],
age: values[1],
category: values[2]
})
onClose()
}
)
Expand Down
Loading

0 comments on commit 009d98a

Please sign in to comment.