feat: Enhance Signup and Chores functionality
- Added query invalidation on signup to refresh user profile data. - Improved MyChores component to ensure data is loaded before rendering. - Introduced dynamic sidepanel configuration with drag-and-drop functionality. - Created TasksByAssigneeCard to visualize tasks assigned to users. - Updated MFASettings and Settings components for better structure and usability. - Implemented SettingsOverview for a comprehensive settings navigation experience. - Added SidepanelSettings for customizing sidepanel card visibility and order. - Refactored NavBar to include user profile avatar and improved layout.
This commit is contained in:
218
src/utils/StatusBarManager.js
Normal file
218
src/utils/StatusBarManager.js
Normal file
@@ -0,0 +1,218 @@
|
||||
import { Capacitor } from '@capacitor/core'
|
||||
import { StatusBar, Style } from '@capacitor/status-bar'
|
||||
import { SafeArea } from 'capacitor-plugin-safe-area'
|
||||
|
||||
/**
|
||||
* StatusBarManager - A utility class to handle status bar configuration
|
||||
* following Capacitor best practices and theme-aware styling
|
||||
*/
|
||||
class StatusBarManager {
|
||||
constructor() {
|
||||
this.isNativePlatform = Capacitor.isNativePlatform()
|
||||
this.platform = Capacitor.getPlatform()
|
||||
this.listeners = []
|
||||
this.currentTheme = 'light'
|
||||
this.safeAreaApplied = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the status bar with proper configuration
|
||||
* @param {string} initialTheme - The initial theme ('light' | 'dark' | 'system')
|
||||
*/
|
||||
async initialize(initialTheme = 'light') {
|
||||
if (!this.isNativePlatform) {
|
||||
console.log('StatusBarManager: Not running on native platform')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
// Configure basic status bar settings - use overlay: true for precise control
|
||||
await StatusBar.setOverlaysWebView({ overlay: false })
|
||||
await StatusBar.show()
|
||||
|
||||
// Set initial theme
|
||||
await this.setTheme(initialTheme)
|
||||
|
||||
// Apply safe area insets
|
||||
await this.applySafeAreaInsets()
|
||||
|
||||
console.log('StatusBarManager: Initialized successfully')
|
||||
} catch (error) {
|
||||
console.error('StatusBarManager: Failed to initialize:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set status bar style based on theme
|
||||
* @param {string} theme - The theme ('light' | 'dark' | 'system')
|
||||
*/
|
||||
async setTheme(theme) {
|
||||
if (!this.isNativePlatform) return
|
||||
|
||||
this.currentTheme = theme
|
||||
|
||||
try {
|
||||
let style = Style.Light // Default to light content (dark status bar)
|
||||
|
||||
if (theme === 'dark') {
|
||||
style = Style.Dark // Dark content (light status bar)
|
||||
} else if (theme === 'system') {
|
||||
// For system theme, we need to detect the actual system preference
|
||||
// Joy UI's useColorScheme will handle this, but we default to light
|
||||
style = Style.Light
|
||||
}
|
||||
|
||||
await StatusBar.setStyle({ style })
|
||||
console.log(`StatusBarManager: Theme set to ${theme}, style: ${style}`)
|
||||
} catch (error) {
|
||||
console.error('StatusBarManager: Failed to set theme:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply safe area insets using CSS custom properties
|
||||
* Components should use env() variables or CSS custom properties for proper safe area handling
|
||||
*/
|
||||
async applySafeAreaInsets() {
|
||||
if (!this.isNativePlatform || this.safeAreaApplied) return
|
||||
|
||||
try {
|
||||
// Get safe area insets
|
||||
const { insets } = await SafeArea.getSafeAreaInsets()
|
||||
|
||||
// Apply CSS custom properties for safe area
|
||||
this.applySafeAreaCSS(insets)
|
||||
|
||||
this.safeAreaApplied = true
|
||||
console.log('StatusBarManager: Safe area insets applied:', insets)
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'StatusBarManager: Failed to apply safe area insets:',
|
||||
error,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply safe area insets using CSS custom properties
|
||||
* @param {Object} insets - The safe area insets
|
||||
*/
|
||||
applySafeAreaCSS(insets) {
|
||||
const root = document.documentElement
|
||||
|
||||
// Set CSS custom properties that can be used throughout the app
|
||||
root.style.setProperty('--safe-area-inset-top', `${insets.top}px`)
|
||||
root.style.setProperty('--safe-area-inset-right', `${insets.right}px`)
|
||||
root.style.setProperty('--safe-area-inset-bottom', `${insets.bottom}px`)
|
||||
root.style.setProperty('--safe-area-inset-left', `${insets.left}px`)
|
||||
|
||||
// Note: We no longer apply padding directly to the body to avoid double
|
||||
// application with component-level safe area handling. Components should
|
||||
// use the CSS custom properties or the utility classes from safe-area.css
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a listener for theme changes
|
||||
* @param {Function} callback - Function to call when theme changes
|
||||
* @returns {Function} - Cleanup function to remove the listener
|
||||
*/
|
||||
addThemeChangeListener(callback) {
|
||||
this.listeners.push(callback)
|
||||
|
||||
// Return cleanup function
|
||||
return () => {
|
||||
const index = this.listeners.indexOf(callback)
|
||||
if (index > -1) {
|
||||
this.listeners.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify all listeners of theme change
|
||||
* @param {string} newTheme - The new theme
|
||||
*/
|
||||
notifyThemeChange(newTheme) {
|
||||
this.listeners.forEach(callback => {
|
||||
try {
|
||||
callback(newTheme)
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'StatusBarManager: Error in theme change listener:',
|
||||
error,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Update status bar based on resolved theme (after system detection)
|
||||
* @param {string} resolvedTheme - The actual theme being used ('light' | 'dark')
|
||||
*/
|
||||
async updateResolvedTheme(resolvedTheme) {
|
||||
if (!this.isNativePlatform) return
|
||||
|
||||
try {
|
||||
const style = resolvedTheme === 'dark' ? Style.Dark : Style.Light
|
||||
await StatusBar.setStyle({ style })
|
||||
console.log(
|
||||
`StatusBarManager: Resolved theme updated to ${resolvedTheme}`,
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('StatusBarManager: Failed to update resolved theme:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the status bar
|
||||
*/
|
||||
async hide() {
|
||||
if (!this.isNativePlatform) return
|
||||
|
||||
try {
|
||||
await StatusBar.hide()
|
||||
} catch (error) {
|
||||
console.error('StatusBarManager: Failed to hide status bar:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the status bar
|
||||
*/
|
||||
async show() {
|
||||
if (!this.isNativePlatform) return
|
||||
|
||||
try {
|
||||
await StatusBar.show()
|
||||
} catch (error) {
|
||||
console.error('StatusBarManager: Failed to show status bar:', error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current status bar info
|
||||
*/
|
||||
async getInfo() {
|
||||
if (!this.isNativePlatform) return null
|
||||
|
||||
try {
|
||||
return await StatusBar.getInfo()
|
||||
} catch (error) {
|
||||
console.error('StatusBarManager: Failed to get status bar info:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up all listeners and reset state
|
||||
*/
|
||||
cleanup() {
|
||||
this.listeners = []
|
||||
this.safeAreaApplied = false
|
||||
console.log('StatusBarManager: Cleaned up')
|
||||
}
|
||||
}
|
||||
|
||||
// Create and export a singleton instance
|
||||
const statusBarManager = new StatusBarManager()
|
||||
export default statusBarManager
|
||||
Reference in New Issue
Block a user