mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-16 13:40:24 +02:00
add player autodj (#7)
This commit is contained in:
@@ -130,6 +130,26 @@ export function calculateNextSong(
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if shuffle is enabled and not in priority mode
|
||||
export function isShuffleEnabled(state: {
|
||||
player: { queueType: PlayerQueueType; shuffle: PlayerShuffle };
|
||||
queue: { shuffled: number[] };
|
||||
}): boolean {
|
||||
return (
|
||||
state.player.shuffle === PlayerShuffle.TRACK &&
|
||||
state.queue.shuffled.length > 0 &&
|
||||
state.player.queueType !== PlayerQueueType.PRIORITY
|
||||
);
|
||||
}
|
||||
|
||||
// Helper function to map shuffled position to actual queue position
|
||||
export function mapShuffledToQueueIndex(shuffledIndex: number, shuffled: number[]): number {
|
||||
if (shuffledIndex >= 0 && shuffledIndex < shuffled.length) {
|
||||
return shuffled[shuffledIndex];
|
||||
}
|
||||
return shuffledIndex;
|
||||
}
|
||||
|
||||
// Helper function to add new indexes to shuffled array after current position
|
||||
function addIndexesToShuffled(
|
||||
shuffled: number[],
|
||||
@@ -206,26 +226,6 @@ function getCombinedQueueLength(priority: string[], defaultQueue: string[]): num
|
||||
return priority.length + defaultQueue.length;
|
||||
}
|
||||
|
||||
// Helper function to check if shuffle is enabled and not in priority mode
|
||||
function isShuffleEnabled(state: {
|
||||
player: { queueType: PlayerQueueType; shuffle: PlayerShuffle };
|
||||
queue: { shuffled: number[] };
|
||||
}): boolean {
|
||||
return (
|
||||
state.player.shuffle === PlayerShuffle.TRACK &&
|
||||
state.queue.shuffled.length > 0 &&
|
||||
state.player.queueType !== PlayerQueueType.PRIORITY
|
||||
);
|
||||
}
|
||||
|
||||
// Helper function to map shuffled position to actual queue position
|
||||
function mapShuffledToQueueIndex(shuffledIndex: number, shuffled: number[]): number {
|
||||
if (shuffledIndex >= 0 && shuffledIndex < shuffled.length) {
|
||||
return shuffled[shuffledIndex];
|
||||
}
|
||||
return shuffledIndex;
|
||||
}
|
||||
|
||||
// Helper function to regenerate shuffled indexes if shuffle is enabled
|
||||
function regenerateShuffledIndexesIfNeeded(state: {
|
||||
player: { queueType: PlayerQueueType; shuffle: PlayerShuffle };
|
||||
|
||||
@@ -401,10 +401,17 @@ const QueryBuilderSettingsSchema = z.object({
|
||||
tag: z.array(QueryBuilderCustomFieldSchema),
|
||||
});
|
||||
|
||||
const AutoDJSettingsSchema = z.object({
|
||||
enabled: z.boolean(),
|
||||
itemCount: z.number(),
|
||||
timing: z.number(),
|
||||
});
|
||||
|
||||
/**
|
||||
* This schema is used for validation of the imported settings json
|
||||
*/
|
||||
export const ValidationSettingsStateSchema = z.object({
|
||||
autoDJ: AutoDJSettingsSchema,
|
||||
css: CssSettingsSchema,
|
||||
discord: DiscordSettingsSchema,
|
||||
font: FontSettingsSchema,
|
||||
@@ -659,6 +666,11 @@ const getPlatformDefaultWindowBarStyle = (): Platform => {
|
||||
const platformDefaultWindowBarStyle: Platform = getPlatformDefaultWindowBarStyle();
|
||||
|
||||
const initialState: SettingsState = {
|
||||
autoDJ: {
|
||||
enabled: false,
|
||||
itemCount: 10,
|
||||
timing: 3,
|
||||
},
|
||||
css: {
|
||||
content: '',
|
||||
enabled: false,
|
||||
@@ -1529,3 +1541,5 @@ export const usePrimaryColor = () => useSettingsStore((store) => store.general.a
|
||||
export const usePlayerbarSlider = () => useSettingsStore((store) => store.general.playerbarSlider);
|
||||
|
||||
export const useGenreTarget = () => useSettingsStore((store) => store.general.genreTarget);
|
||||
|
||||
export const useAutoDJSettings = () => useSettingsStore((store) => store.autoDJ, shallow);
|
||||
|
||||
@@ -30,3 +30,149 @@ export const idbStateStorage: StateStorage = {
|
||||
await set(name, value);
|
||||
},
|
||||
};
|
||||
|
||||
const settingsKeys = [
|
||||
'store_settings_autoDJ',
|
||||
'store_settings_general',
|
||||
'store_settings_lists',
|
||||
'store_settings_hotkeys',
|
||||
'store_settings_playback',
|
||||
'store_settings_lyrics',
|
||||
'store_settings_window',
|
||||
'store_settings_discord',
|
||||
'store_settings_font',
|
||||
'store_settings_css',
|
||||
'store_settings_remote',
|
||||
'store_settings_queryBuilder',
|
||||
'store_settings_tab',
|
||||
];
|
||||
|
||||
export const splitSettingsStorage: StateStorage = {
|
||||
getItem: (name: string): null | string => {
|
||||
if (name !== 'store_settings') {
|
||||
return localStorage.getItem(name);
|
||||
}
|
||||
|
||||
// Read from all split keys and merge them
|
||||
const keys = settingsKeys;
|
||||
|
||||
// Check if old single key exists (for migration)
|
||||
const oldKeyRaw = localStorage.getItem('store_settings');
|
||||
if (oldKeyRaw && !localStorage.getItem('store_settings_general')) {
|
||||
// Only migrate if split keys don't exist yet
|
||||
try {
|
||||
const oldData = JSON.parse(oldKeyRaw);
|
||||
const splitData: Record<string, unknown> = {};
|
||||
const state = oldData.state || oldData;
|
||||
|
||||
if (state && typeof state === 'object') {
|
||||
splitData.general = state.general;
|
||||
splitData.lists = state.lists;
|
||||
splitData.hotkeys = state.hotkeys;
|
||||
splitData.playback = state.playback;
|
||||
splitData.lyrics = state.lyrics;
|
||||
splitData.window = state.window;
|
||||
splitData.discord = state.discord;
|
||||
splitData.font = state.font;
|
||||
splitData.css = state.css;
|
||||
splitData.remote = state.remote;
|
||||
splitData.queryBuilder = state.queryBuilder;
|
||||
splitData.tab = state.tab;
|
||||
|
||||
// Save to new split keys
|
||||
keys.forEach((key) => {
|
||||
const keyName = key.replace('store_settings_', '');
|
||||
if (splitData[keyName] !== undefined) {
|
||||
localStorage.setItem(key, JSON.stringify(splitData[keyName]));
|
||||
}
|
||||
});
|
||||
|
||||
// Store version if it exists
|
||||
if (oldData.version !== undefined) {
|
||||
localStorage.setItem('store_settings_version', oldData.version.toString());
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// If parsing fails, continue with reading from split keys
|
||||
console.warn('Failed to migrate old settings format:', e);
|
||||
}
|
||||
}
|
||||
|
||||
// Read from all split keys
|
||||
const mergedState: Record<string, unknown> = {};
|
||||
let hasData = false;
|
||||
|
||||
keys.forEach((key) => {
|
||||
const value = localStorage.getItem(key);
|
||||
if (value) {
|
||||
try {
|
||||
const keyName = key.replace('store_settings_', '');
|
||||
mergedState[keyName] = JSON.parse(value);
|
||||
hasData = true;
|
||||
} catch (e) {
|
||||
console.warn(`Failed to parse ${key}:`, e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const versionKey = localStorage.getItem('store_settings_version');
|
||||
const version = versionKey ? parseInt(versionKey, 10) : 14;
|
||||
|
||||
return JSON.stringify({
|
||||
state: mergedState,
|
||||
version,
|
||||
});
|
||||
},
|
||||
|
||||
removeItem: (name: string): void => {
|
||||
if (name !== 'store_settings') {
|
||||
localStorage.removeItem(name);
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove all split keys
|
||||
const keys = settingsKeys;
|
||||
|
||||
keys.forEach((key) => {
|
||||
localStorage.removeItem(key);
|
||||
});
|
||||
|
||||
// Also remove old key if it exists
|
||||
localStorage.removeItem('store_settings');
|
||||
},
|
||||
|
||||
setItem: (name: string, value: string): void => {
|
||||
if (name !== 'store_settings') {
|
||||
localStorage.setItem(name, value);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = JSON.parse(value);
|
||||
const state = data.state || data;
|
||||
|
||||
const keys = settingsKeys.map((key) => ({
|
||||
key,
|
||||
value: state[key as keyof typeof state],
|
||||
}));
|
||||
|
||||
keys.forEach(({ key, value: keyValue }) => {
|
||||
if (keyValue !== undefined) {
|
||||
localStorage.setItem(key, JSON.stringify(keyValue));
|
||||
}
|
||||
});
|
||||
|
||||
// Store version separately
|
||||
if (data.version !== undefined) {
|
||||
localStorage.setItem('store_settings_version', data.version.toString());
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to split settings storage:', e);
|
||||
localStorage.setItem(name, value);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user