fluxer/fluxer_app/src/stores/CompactVoiceCallPiPPositionStore.tsx
2026-02-17 12:22:36 +00:00

83 lines
2.5 KiB
TypeScript

/*
* Copyright (C) 2026 Fluxer Contributors
*
* This file is part of Fluxer.
*
* Fluxer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Fluxer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
*/
import AppStorage from '@app/lib/AppStorage';
import {makeAutoObservable} from 'mobx';
interface CompactVoiceCallPiPPositionState {
x: number;
y: number;
}
const COMPACT_VOICE_CALL_PIP_POSITION_KEY = 'compact_voice_call_pip_position';
const DEFAULT_COMPACT_PIP_POSITION: CompactVoiceCallPiPPositionState = {
x: 1,
y: 0,
};
function clampNormalizedValue(value: unknown, fallback: number): number {
if (typeof value !== 'number' || !Number.isFinite(value)) {
return fallback;
}
return Math.max(0, Math.min(1, value));
}
function parseCompactVoiceCallPiPPosition(value: unknown): CompactVoiceCallPiPPositionState {
if (typeof value !== 'object' || value == null || Array.isArray(value)) {
return DEFAULT_COMPACT_PIP_POSITION;
}
const state = value as Record<string, unknown>;
return {
x: clampNormalizedValue(state.x, DEFAULT_COMPACT_PIP_POSITION.x),
y: clampNormalizedValue(state.y, DEFAULT_COMPACT_PIP_POSITION.y),
};
}
class CompactVoiceCallPiPPositionStore {
x = DEFAULT_COMPACT_PIP_POSITION.x;
y = DEFAULT_COMPACT_PIP_POSITION.y;
constructor() {
makeAutoObservable(this, {}, {autoBind: true});
const initialState = parseCompactVoiceCallPiPPosition(
AppStorage.getJSON<unknown>(COMPACT_VOICE_CALL_PIP_POSITION_KEY),
);
this.x = initialState.x;
this.y = initialState.y;
}
getPosition(): CompactVoiceCallPiPPositionState {
return {
x: this.x,
y: this.y,
};
}
setPosition(position: CompactVoiceCallPiPPositionState): void {
this.x = clampNormalizedValue(position.x, DEFAULT_COMPACT_PIP_POSITION.x);
this.y = clampNormalizedValue(position.y, DEFAULT_COMPACT_PIP_POSITION.y);
AppStorage.setJSON(COMPACT_VOICE_CALL_PIP_POSITION_KEY, {
x: this.x,
y: this.y,
});
}
}
export default new CompactVoiceCallPiPPositionStore();