mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 13:47:57 +03:00
Fetch titles from tags to show in playlist.
This commit is contained in:
parent
2c6b76965b
commit
dca9bf3531
4 changed files with 68 additions and 3 deletions
|
@ -1,6 +1,6 @@
|
|||
import { configureStore, createAsyncThunk, createReducer } from "@reduxjs/toolkit";
|
||||
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
|
||||
import { PsfPlayerModule, initPsfPlayerModule, resumePsf, pausePsf, getPsfArchiveFileList, loadPsfFromArchive, getCurrentPsfTags } from "./PsfPlayerModule";
|
||||
import { PsfPlayerModule, initPsfPlayerModule, resumePsf, pausePsf, getPsfArchiveFileList, getPsfArchiveItemTags, loadPsfFromArchive, getCurrentPsfTags } from "./PsfPlayerModule";
|
||||
|
||||
const invalidPlayingIndex = -1;
|
||||
|
||||
|
@ -26,6 +26,7 @@ export type AudioState = {
|
|||
playing: boolean
|
||||
playingIndex: number
|
||||
archiveFileList : string[]
|
||||
archiveItemTitles : string[]
|
||||
archiveFileListVersion : number;
|
||||
currentPsfTags : any | undefined
|
||||
};
|
||||
|
@ -41,6 +42,7 @@ let initialState : AudioState = {
|
|||
playing: false,
|
||||
playingIndex: invalidPlayingIndex,
|
||||
archiveFileList: [],
|
||||
archiveItemTitles: [],
|
||||
archiveFileListVersion: 0,
|
||||
currentPsfTags: undefined
|
||||
};
|
||||
|
@ -84,6 +86,20 @@ export const loadArchive = createAsyncThunk<string[] | undefined, File>('loadArc
|
|||
}
|
||||
);
|
||||
|
||||
export const fetchArchiveItemTitle = createAsyncThunk<string, number>('fetchArchiveItemTitle',
|
||||
async (archiveFileIndex : number, thunkAPI) => {
|
||||
let state = thunkAPI.getState() as RootState;
|
||||
let psfFilePath = state.player.archiveFileList[archiveFileIndex] as string;
|
||||
let tags = getPsfArchiveItemTags(archiveFilePath, psfFilePath);
|
||||
let title = tags.get("title");
|
||||
if(title) {
|
||||
return title;
|
||||
} else {
|
||||
return psfFilePath;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export const loadPsf = createAsyncThunk<LoadPsfResult, number>('loadPsf',
|
||||
async (archiveFileIndex : number, thunkAPI) => {
|
||||
let state = thunkAPI.getState() as RootState;
|
||||
|
@ -122,8 +138,10 @@ const reducer = createReducer(initialState, (builder) => (
|
|||
state.currentPsfTags = undefined;
|
||||
if(action.payload) {
|
||||
state.archiveFileList = action.payload;
|
||||
state.archiveItemTitles = [...action.payload];
|
||||
} else {
|
||||
state.archiveFileList = [];
|
||||
state.archiveItemTitles = [];
|
||||
}
|
||||
state.archiveFileListVersion = state.archiveFileListVersion + 1;
|
||||
return state;
|
||||
|
@ -132,10 +150,15 @@ const reducer = createReducer(initialState, (builder) => (
|
|||
state.playingIndex = invalidPlayingIndex;
|
||||
state.currentPsfTags = undefined;
|
||||
state.archiveFileList = [];
|
||||
state.archiveItemTitles = [];
|
||||
state.archiveFileListVersion = state.archiveFileListVersion + 1;
|
||||
state.value = `loading failed: ${action.error.message}`;
|
||||
return state;
|
||||
})
|
||||
.addCase(fetchArchiveItemTitle.fulfilled, (state, action) => {
|
||||
state.archiveItemTitles[action.meta.arg] = action.payload;
|
||||
return state;
|
||||
})
|
||||
.addCase(loadPsf.fulfilled, (state, action) => {
|
||||
state.value = "psf loaded";
|
||||
state.currentPsfTags = action.payload.tags;
|
||||
|
|
|
@ -2,7 +2,7 @@ import './App.css';
|
|||
import { ChangeEvent, useEffect, useRef } from 'react';
|
||||
import { FixedSizeList, ListChildComponentProps } from 'react-window';
|
||||
import { ListItem, ListItemButton, ListItemText } from '@mui/material';
|
||||
import { useAppDispatch, useAppSelector, loadArchive, loadPsf, play, pause } from "./Actions";
|
||||
import { useAppDispatch, useAppSelector, loadArchive, fetchArchiveItemTitle, loadPsf, play, pause } from "./Actions";
|
||||
import { PsfPlayerModule } from './PsfPlayerModule';
|
||||
|
||||
function RenderRow(props: ListChildComponentProps) {
|
||||
|
@ -10,6 +10,7 @@ function RenderRow(props: ListChildComponentProps) {
|
|||
|
||||
const state = useAppSelector((state) => state.player);
|
||||
let archiveFile = state.archiveFileList[index];
|
||||
let archiveItemTitle = state.archiveItemTitles[index];
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
const handleClick = function(archiveFileIndex : number) {
|
||||
|
@ -24,7 +25,7 @@ function RenderRow(props: ListChildComponentProps) {
|
|||
return (
|
||||
<ListItem style={style} key={index} component="div" disablePadding>
|
||||
<ListItemButton onClick={(e) => handleClick(index)}>
|
||||
<ListItemText primary={archiveFile} primaryTypographyProps={{style: itemStyle}} />
|
||||
<ListItemText primary={archiveItemTitle} primaryTypographyProps={{style: itemStyle}} />
|
||||
</ListItemButton>
|
||||
</ListItem>
|
||||
);
|
||||
|
@ -38,6 +39,8 @@ function usePrevious<Type>(value : Type) : Type | undefined {
|
|||
return ref.current;
|
||||
}
|
||||
|
||||
let fetchTitleAbortController = new AbortController();
|
||||
|
||||
export default function App() {
|
||||
const dispatch = useAppDispatch();
|
||||
const listRef = useRef<FixedSizeList>(null);
|
||||
|
@ -82,13 +85,36 @@ export default function App() {
|
|||
|
||||
const handleChange = function(event : ChangeEvent<HTMLInputElement>) {
|
||||
if(event.target && event.target.files && event.target.files.length !== 0) {
|
||||
fetchTitleAbortController.abort();
|
||||
dispatch(loadArchive(event.target.files[0]));
|
||||
}
|
||||
}
|
||||
|
||||
const fetchTitles = async function(signal : AbortSignal) {
|
||||
function sleep(ms : number) {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
let fetchPromiseAbortFunction : Function | null = null;
|
||||
signal.addEventListener("abort", (ev: Event) => {
|
||||
if(fetchPromiseAbortFunction) {
|
||||
fetchPromiseAbortFunction();
|
||||
}
|
||||
});
|
||||
for(let i = 0; i < state.archiveFileList.length; i++) {
|
||||
await sleep(100);
|
||||
if(signal.aborted) {
|
||||
break;
|
||||
}
|
||||
let fetchPromise = dispatch(fetchArchiveItemTitle(i));
|
||||
fetchPromiseAbortFunction = fetchPromise.abort;
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if(state.archiveFileListVersion !== prevArchiveFileListVersion) {
|
||||
listRef.current?.scrollTo(0);
|
||||
fetchTitleAbortController = new AbortController();
|
||||
fetchTitles(fetchTitleAbortController.signal);
|
||||
}
|
||||
if(state.playing !== prevPlaying) {
|
||||
if(state.playing) {
|
||||
|
|
|
@ -53,6 +53,11 @@ export let getPsfArchiveFileList = function(archivePath : string) {
|
|||
return convertStringVectorToArray(fileList);
|
||||
}
|
||||
|
||||
export let getPsfArchiveItemTags = function(archivePath : string, psfPath : string) {
|
||||
let tags = convertStringMapToDictionary(PsfPlayerModule.getPsfArchiveItemTags(archivePath, psfPath));
|
||||
return tags;
|
||||
}
|
||||
|
||||
export let loadPsfFromArchive = async function(archivePath : string, psfPath : string) {
|
||||
PsfPlayerModule.loadPsf(archivePath, psfPath);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <cstdio>
|
||||
#include "filesystem_def.h"
|
||||
#include "PsfArchive.h"
|
||||
#include "PsfStreamProvider.h"
|
||||
#include "SH_OpenALProxy.h"
|
||||
#include "SH_FileOutput.h"
|
||||
#include "../SH_OpenAL.h"
|
||||
|
@ -79,6 +80,15 @@ std::vector<std::string> getPsfArchiveFileList(std::string rawArchivePath)
|
|||
return result;
|
||||
}
|
||||
|
||||
CPsfBase::TagMap getPsfArchiveItemTags(std::string rawArchivePath, std::string psfPath)
|
||||
{
|
||||
fs::path archivePath(rawArchivePath);
|
||||
auto streamProvider = CreatePsfStreamProvider(archivePath);
|
||||
std::unique_ptr<Framework::CStream> inputStream(streamProvider->GetStreamForPath(psfPath));
|
||||
CPsfBase psfFile(*inputStream);
|
||||
return CPsfBase::TagMap(psfFile.GetTagsBegin(), psfFile.GetTagsEnd());
|
||||
}
|
||||
|
||||
CPsfBase::TagMap getCurrentPsfTags()
|
||||
{
|
||||
return g_tags;
|
||||
|
@ -95,5 +105,6 @@ EMSCRIPTEN_BINDINGS(PsfPlayer)
|
|||
function("resumePsf", &resumePsf);
|
||||
function("loadPsf", &loadPsf);
|
||||
function("getPsfArchiveFileList", &getPsfArchiveFileList);
|
||||
function("getPsfArchiveItemTags", &getPsfArchiveItemTags);
|
||||
function("getCurrentPsfTags", &getCurrentPsfTags);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue