diff --git a/assets/images/123.jpg b/assets/images/123.jpg new file mode 100644 index 0000000..e6c7684 Binary files /dev/null and b/assets/images/123.jpg differ diff --git a/assets/images/456.jpg b/assets/images/456.jpg new file mode 100644 index 0000000..da767ba Binary files /dev/null and b/assets/images/456.jpg differ diff --git a/assets/images/bathroom.webp b/assets/images/bathroom.webp new file mode 100644 index 0000000..ed68b9e Binary files /dev/null and b/assets/images/bathroom.webp differ diff --git a/assets/images/fallFactor.webp b/assets/images/fallFactor.webp new file mode 100644 index 0000000..66eced2 Binary files /dev/null and b/assets/images/fallFactor.webp differ diff --git a/assets/images/fallRescue1.webp b/assets/images/fallRescue1.webp new file mode 100644 index 0000000..03eb7aa Binary files /dev/null and b/assets/images/fallRescue1.webp differ diff --git a/assets/images/fallRescue2.webp b/assets/images/fallRescue2.webp new file mode 100644 index 0000000..f74cfc6 Binary files /dev/null and b/assets/images/fallRescue2.webp differ diff --git a/lib/MessagePage.dart b/lib/MessagePage.dart index 3b2b48f..1ebd280 100644 --- a/lib/MessagePage.dart +++ b/lib/MessagePage.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:mysql_client/mysql_client.dart'; +import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart'; import 'package:webview_flutter/webview_flutter.dart'; class MessagePage extends StatefulWidget { @@ -13,6 +15,7 @@ class MessagePage extends StatefulWidget { class _MessagePageState extends State { late WebViewController _webViewController; + late int _cameraId = 0; @override void initState() { @@ -23,92 +26,116 @@ class _MessagePageState extends State { @override Widget build(BuildContext context) { return Scaffold( - body: Center( - child: Column( - children: [ - Container( - height: 100, - // APPBar height - color: Color(0xFFF5E3C3), - width: double.infinity, - padding: EdgeInsets.all(10.0), - child: Stack(children: [ - Container( - padding: EdgeInsets.only( - left: MediaQuery.of(context).size.width, - top: MediaQuery.of(context).size.height / 2, - ), - child: Icon(Icons.settings, size: 48, color: Colors.orange), + body: Center( + child: Column( + children: [ + Container( + height: 100, + // APPBar height + color: Color(0xFFF5E3C3), + width: double.infinity, + padding: EdgeInsets.all(10.0), + child: Stack(children: [ + Container( + padding: EdgeInsets.only( + left: MediaQuery.of(context).size.width, + top: MediaQuery.of(context).size.height / 2, ), - Center( - child: Text( - '全方位照護守護者', - style: TextStyle(fontSize: 24, height: 5), - ), + child: Icon(Icons.settings, size: 48, color: Colors.orange), + ), + Center( + child: Text( + '全方位照護守護者', + style: TextStyle(fontSize: 24, height: 5), ), - ])), - Container( - color: Color(0xFFFFF0E0), - margin: EdgeInsets.only(top: 5), - padding: EdgeInsets.all(16), - child: Column( - children: [ - Container( - height: 240, - width: double.infinity, - // TODO: 如果用http需要分別設定ios, android權限 - child: WebViewWidget( - controller: _webViewController - ..setJavaScriptMode(JavaScriptMode.unrestricted) - ..setNavigationDelegate( - NavigationDelegate( - onProgress: (int progress) { - // Update loading bar. - }, - onPageStarted: (String url) {}, - onPageFinished: (String url) {}, - onHttpError: (HttpResponseError error) { - print("httpError"); - }, - onWebResourceError: (WebResourceError error) { - print("httpResourceError"); - print(error.description); - }, - onNavigationRequest: (NavigationRequest request) { - if (request.url.startsWith( - 'http://203.64.84.154:8088/video_feed')) { - return NavigationDecision.prevent; - } - return NavigationDecision.navigate; - }, + ), + ])), + Container( + color: Color(0xFFFFF0E0), + margin: EdgeInsets.only(top: 5), + padding: EdgeInsets.all(16), + child: Column( + children: [ + Container( + height: 240, + width: double.infinity, + child: Stack( + children: [ + WebViewWidget( + controller: _webViewController + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) {}, + onHttpError: (HttpResponseError error) { + print("httpError"); + }, + onWebResourceError: (WebResourceError error) { + print("httpResourceError"); + print(error.description); + }, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('http://203.64.84.154:8088/video_feed')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse('http://203.64.84.154:8088/0')), + ), + Align( + alignment: Alignment.bottomRight, + child: Padding( + padding: EdgeInsets.all(16.0), + // Adjust padding as needed + child: SizedBox( + width: 45.0, // Set custom width + height: 45.0, // Set custom height + child: FloatingActionButton( + onPressed: () { + // Handle zoom-in action + pushWithoutNavBar( + context, + MaterialPageRoute( + builder: (context) => WebViewPage(_cameraId), + )); + }, + child: Icon(Icons.zoom_in), + ), ), - ) - ..loadRequest(Uri.parse('http://203.64.84.154:8088/0')), - ), + ), + ), + ], ), - Text( - '即時畫面', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - ], - ), + ), + Text( + '即時畫面', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + ], ), - Expanded( - child: GridView.count( - crossAxisCount: 2, - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - padding: EdgeInsets.all(16), - children: [ - _buildGridItem(Icons.monitor_outlined, '畫面1', 0, context), - _buildGridItem(Icons.monitor_outlined, '畫面2', 1, context), - ], - ), + ), + Expanded( + child: GridView.count( + crossAxisCount: 2, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + padding: EdgeInsets.all(16), + children: [ + _buildGridItem(Icons.monitor_outlined, '畫面1', 0, context), + _buildGridItem(Icons.monitor_outlined, '畫面2', 1, context), + ], ), - ], - ), + ), + ], ), - ); + ), + ); } Widget _buildGridItem(IconData icon, String label, int camera_id, BuildContext context) { @@ -119,6 +146,7 @@ class _MessagePageState extends State { color: Colors.white, child: InkWell( onTap: () { + _cameraId = camera_id; _webViewController.loadRequest(Uri.parse('http://203.64.84.154:8088/$camera_id')); }, child: Center( @@ -135,3 +163,92 @@ class _MessagePageState extends State { ); } } + +class WebViewPage extends StatefulWidget { + final int _cameraId; + + WebViewPage(this._cameraId); + + @override + _WebViewPageState createState() => _WebViewPageState(); +} + +class _WebViewPageState extends State { + late WebViewController _webViewController; + + @override + void initState() { + super.initState(); + SystemChrome.setPreferredOrientations([ + DeviceOrientation.landscapeLeft, + DeviceOrientation.landscapeRight, + ]); + _webViewController = WebViewController(); + } + + @override + void dispose() { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + WebViewWidget( + controller: _webViewController + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) { + // Update loading bar. + }, + onPageStarted: (String url) {}, + onPageFinished: (String url) {}, + onHttpError: (HttpResponseError error) { + print("httpError"); + }, + onWebResourceError: (WebResourceError error) { + print("httpResourceError"); + print(error.description); + }, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('http://203.64.84.154:8088/video_feed')) { + return NavigationDecision.prevent; + } + return NavigationDecision.navigate; + }, + ), + ) + ..loadRequest(Uri.parse('http://203.64.84.154:8088/${widget._cameraId}')), + ), + Align( + alignment: Alignment.bottomRight, + child: Padding( + padding: EdgeInsets.all(16.0), + child: SizedBox( + width: 45.0, + height: 45.0, + child: FloatingActionButton( + backgroundColor: Color(0xFFF5E3C3), + onPressed: () { + SystemChrome.setPreferredOrientations([ + DeviceOrientation.portraitUp, + DeviceOrientation.portraitDown, + ]); + Navigator.pop(context); + }, + child: Icon(Icons.arrow_back_ios), + ), + ), + ), + ) + ], + )); + } +} diff --git a/lib/PersonalInfo.dart b/lib/PersonalInfo.dart index 40af7d3..2b236c8 100644 --- a/lib/PersonalInfo.dart +++ b/lib/PersonalInfo.dart @@ -202,21 +202,21 @@ class _PersonalInfoState extends State { Divider(), Divider(), - ElevatedButton( - onPressed: () { - if (_isEditing) { - _saveChanges(); - } else { - _toggleEdit(); - } - }, - child: Text(_isEditing ? '儲存變更' : '修改資料'), - style: TextButton.styleFrom( - backgroundColor: Color(0xFFF5E3C3), - textStyle: TextStyle(fontSize: 18), - shadowColor: Colors.transparent, - ), - ), + // ElevatedButton( + // onPressed: () { + // if (_isEditing) { + // _saveChanges(); + // } else { + // _toggleEdit(); + // } + // }, + // child: Text(_isEditing ? '儲存變更' : '修改資料'), + // style: TextButton.styleFrom( + // backgroundColor: Color(0xFFF5E3C3), + // textStyle: TextStyle(fontSize: 18), + // shadowColor: Colors.transparent, + // ), + // ), ElevatedButton( onPressed: _loginOut, child: Text('登出'),