Fix form keyboard issues and sticky footers in agent screens
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { useAppDispatch } from '../../../app/hooks';
|
||||
import { haptics } from '../../../services/haptics/haptics';
|
||||
import { uiActions } from '../store/uiSlice';
|
||||
|
||||
export const useToastQueue = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
return useCallback(
|
||||
(title: string, type: 'success' | 'error' | 'info', description?: string) => {
|
||||
if (type === 'success') {
|
||||
haptics.success();
|
||||
} else if (type === 'error') {
|
||||
haptics.error();
|
||||
} else {
|
||||
haptics.selection();
|
||||
}
|
||||
|
||||
dispatch(
|
||||
uiActions.showToast({
|
||||
id: `${Date.now()}_${type}`,
|
||||
title,
|
||||
type,
|
||||
description,
|
||||
}),
|
||||
);
|
||||
},
|
||||
[dispatch],
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
import type { RootState } from '../../../app/store';
|
||||
|
||||
export const selectUiState = (state: RootState) => state.ui;
|
||||
export const selectToasts = (state: RootState) => state.ui.toasts;
|
||||
export const selectSessionExpired = (state: RootState) => state.ui.sessionExpired;
|
||||
@@ -0,0 +1,40 @@
|
||||
import { createSlice, type PayloadAction } from '@reduxjs/toolkit';
|
||||
|
||||
import type { ToastMessage } from '../../../types/app';
|
||||
import { markAppReady } from './uiThunk';
|
||||
|
||||
interface UiState {
|
||||
appReady: boolean;
|
||||
sessionExpired: boolean;
|
||||
toasts: ToastMessage[];
|
||||
}
|
||||
|
||||
const initialState: UiState = {
|
||||
appReady: false,
|
||||
sessionExpired: false,
|
||||
toasts: [],
|
||||
};
|
||||
|
||||
const uiSlice = createSlice({
|
||||
name: 'ui',
|
||||
initialState,
|
||||
reducers: {
|
||||
showToast(state, action: PayloadAction<ToastMessage>) {
|
||||
state.toasts.push(action.payload);
|
||||
},
|
||||
dismissToast(state, action: PayloadAction<string>) {
|
||||
state.toasts = state.toasts.filter((toast) => toast.id !== action.payload);
|
||||
},
|
||||
setSessionExpired(state, action: PayloadAction<boolean>) {
|
||||
state.sessionExpired = action.payload;
|
||||
},
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
builder.addCase(markAppReady.fulfilled, (state) => {
|
||||
state.appReady = true;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export const uiActions = uiSlice.actions;
|
||||
export const uiReducer = uiSlice.reducer;
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createAsyncThunk } from '@reduxjs/toolkit';
|
||||
|
||||
import { sleep } from '../../../utils/async';
|
||||
|
||||
export const markAppReady = createAsyncThunk('ui/markAppReady', async () => {
|
||||
await sleep(100);
|
||||
return true;
|
||||
});
|
||||
Reference in New Issue
Block a user