Add call history, dark mode toggle, caller ID persistence, and refactor phone page
Phone page improvements: - Clear caller number display after call disconnects - Add "Recent" tab with session call history (tap to call back) - Persist outbound caller ID selection in localStorage - Fix button overlap with proper z-index layering - Add manual dark mode toggle (System/Light/Dark) in Settings - Improve dark mode CSS for all UI elements Refactor phone page into separate files: - assets/mobile/phone.css (848 lines) — all CSS - assets/mobile/phone.js (1065 lines) — all JavaScript - assets/mobile/phone-template.php (267 lines) — HTML template - includes/class-twp-mobile-phone-page.php (211 lines) — PHP controller - PHP values passed to JS via window.twpConfig bridge Flutter app: - Replace FAB with slim AppBar (refresh + menu buttons) - Fix dark mode colors using theme-aware colorScheme Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -194,35 +194,6 @@ class _PhoneScreenState extends State<PhoneScreen> with WidgetsBindingObserver {
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
void _showMenu() {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => SafeArea(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ListTile(
|
||||
leading: const Icon(Icons.refresh),
|
||||
title: const Text('Reload'),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
_controller.reload();
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.logout),
|
||||
title: const Text('Logout'),
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
_confirmLogout();
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _confirmLogout() async {
|
||||
final result = await showDialog<bool>(
|
||||
context: context,
|
||||
@@ -256,7 +227,45 @@ class _PhoneScreenState extends State<PhoneScreen> with WidgetsBindingObserver {
|
||||
return WillPopScope(
|
||||
onWillPop: _onWillPop,
|
||||
child: Scaffold(
|
||||
appBar: _hasError
|
||||
? null
|
||||
: AppBar(
|
||||
toolbarHeight: 40,
|
||||
titleSpacing: 12,
|
||||
title: Text(
|
||||
'TWP Softphone',
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.refresh, size: 20),
|
||||
tooltip: 'Reload',
|
||||
visualDensity: VisualDensity.compact,
|
||||
onPressed: () => _controller.reload(),
|
||||
),
|
||||
PopupMenuButton<String>(
|
||||
icon: const Icon(Icons.more_vert, size: 20),
|
||||
tooltip: 'Menu',
|
||||
padding: EdgeInsets.zero,
|
||||
onSelected: (value) {
|
||||
if (value == 'logout') _confirmLogout();
|
||||
},
|
||||
itemBuilder: (context) => [
|
||||
const PopupMenuItem(
|
||||
value: 'logout',
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.logout),
|
||||
title: Text('Logout'),
|
||||
dense: true,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
body: SafeArea(
|
||||
top: _hasError, // AppBar already handles top safe area when visible
|
||||
child: Stack(
|
||||
children: [
|
||||
if (!_hasError) WebViewWidget(controller: _controller),
|
||||
@@ -266,34 +275,33 @@ class _PhoneScreenState extends State<PhoneScreen> with WidgetsBindingObserver {
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: (!_hasError && !_loading)
|
||||
? FloatingActionButton.small(
|
||||
onPressed: _showMenu,
|
||||
child: const Icon(Icons.more_vert),
|
||||
)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildErrorView() {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.wifi_off, size: 64, color: Colors.grey),
|
||||
Icon(Icons.wifi_off, size: 64, color: colorScheme.onSurfaceVariant),
|
||||
const SizedBox(height: 16),
|
||||
const Text(
|
||||
Text(
|
||||
'Connection Error',
|
||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: colorScheme.onSurface,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
_errorMessage ?? 'Could not load the phone page.',
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(color: Colors.grey),
|
||||
style: TextStyle(color: colorScheme.onSurfaceVariant),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
FilledButton.icon(
|
||||
|
||||
Reference in New Issue
Block a user