Merge remote-tracking branch 'origin/main'

This commit is contained in:
kuei 2024-09-23 20:55:28 +08:00
commit 9addc73193
8 changed files with 211 additions and 94 deletions

BIN
assets/images/123.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
assets/images/456.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
assets/images/bathroom.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -1,5 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mysql_client/mysql_client.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'; import 'package:webview_flutter/webview_flutter.dart';
class MessagePage extends StatefulWidget { class MessagePage extends StatefulWidget {
@ -13,6 +15,7 @@ class MessagePage extends StatefulWidget {
class _MessagePageState extends State<MessagePage> { class _MessagePageState extends State<MessagePage> {
late WebViewController _webViewController; late WebViewController _webViewController;
late int _cameraId = 0;
@override @override
void initState() { void initState() {
@ -23,92 +26,116 @@ class _MessagePageState extends State<MessagePage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
body: Center( body: Center(
child: Column( child: Column(
children: [ children: [
Container( Container(
height: 100, height: 100,
// APPBar height // APPBar height
color: Color(0xFFF5E3C3), color: Color(0xFFF5E3C3),
width: double.infinity, width: double.infinity,
padding: EdgeInsets.all(10.0), padding: EdgeInsets.all(10.0),
child: Stack(children: [ child: Stack(children: [
Container( Container(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: MediaQuery.of(context).size.width, left: MediaQuery.of(context).size.width,
top: MediaQuery.of(context).size.height / 2, top: MediaQuery.of(context).size.height / 2,
),
child: Icon(Icons.settings, size: 48, color: Colors.orange),
), ),
Center( child: Icon(Icons.settings, size: 48, color: Colors.orange),
child: Text( ),
'全方位照護守護者', Center(
style: TextStyle(fontSize: 24, height: 5), child: Text(
), '全方位照護守護者',
style: TextStyle(fontSize: 24, height: 5),
), ),
])), ),
Container( ])),
color: Color(0xFFFFF0E0), Container(
margin: EdgeInsets.only(top: 5), color: Color(0xFFFFF0E0),
padding: EdgeInsets.all(16), margin: EdgeInsets.only(top: 5),
child: Column( padding: EdgeInsets.all(16),
children: [ child: Column(
Container( children: [
height: 240, Container(
width: double.infinity, height: 240,
// TODO: http需要分別設定ios, android權限 width: double.infinity,
child: WebViewWidget( child: Stack(
controller: _webViewController children: [
..setJavaScriptMode(JavaScriptMode.unrestricted) WebViewWidget(
..setNavigationDelegate( controller: _webViewController
NavigationDelegate( ..setJavaScriptMode(JavaScriptMode.unrestricted)
onProgress: (int progress) { ..setNavigationDelegate(
// Update loading bar. NavigationDelegate(
}, onProgress: (int progress) {
onPageStarted: (String url) {}, // Update loading bar.
onPageFinished: (String url) {}, },
onHttpError: (HttpResponseError error) { onPageStarted: (String url) {},
print("httpError"); onPageFinished: (String url) {},
}, onHttpError: (HttpResponseError error) {
onWebResourceError: (WebResourceError error) { print("httpError");
print("httpResourceError"); },
print(error.description); onWebResourceError: (WebResourceError error) {
}, print("httpResourceError");
onNavigationRequest: (NavigationRequest request) { print(error.description);
if (request.url.startsWith( },
'http://203.64.84.154:8088/video_feed')) { onNavigationRequest: (NavigationRequest request) {
return NavigationDecision.prevent; if (request.url.startsWith('http://203.64.84.154:8088/video_feed')) {
} return NavigationDecision.prevent;
return NavigationDecision.navigate; }
}, 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( ),
'即時畫面', Text(
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), '即時畫面',
), style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
], ),
), ],
), ),
Expanded( ),
child: GridView.count( Expanded(
crossAxisCount: 2, child: GridView.count(
shrinkWrap: true, crossAxisCount: 2,
physics: NeverScrollableScrollPhysics(), shrinkWrap: true,
padding: EdgeInsets.all(16), physics: NeverScrollableScrollPhysics(),
children: [ padding: EdgeInsets.all(16),
_buildGridItem(Icons.monitor_outlined, '畫面1', 0, context), children: [
_buildGridItem(Icons.monitor_outlined, '畫面2', 1, context), _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) { Widget _buildGridItem(IconData icon, String label, int camera_id, BuildContext context) {
@ -119,6 +146,7 @@ class _MessagePageState extends State<MessagePage> {
color: Colors.white, color: Colors.white,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
_cameraId = camera_id;
_webViewController.loadRequest(Uri.parse('http://203.64.84.154:8088/$camera_id')); _webViewController.loadRequest(Uri.parse('http://203.64.84.154:8088/$camera_id'));
}, },
child: Center( child: Center(
@ -135,3 +163,92 @@ class _MessagePageState extends State<MessagePage> {
); );
} }
} }
class WebViewPage extends StatefulWidget {
final int _cameraId;
WebViewPage(this._cameraId);
@override
_WebViewPageState createState() => _WebViewPageState();
}
class _WebViewPageState extends State<WebViewPage> {
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),
),
),
),
)
],
));
}
}

View File

@ -202,21 +202,21 @@ class _PersonalInfoState extends State<PersonalInfo> {
Divider(), Divider(),
Divider(), Divider(),
ElevatedButton( // ElevatedButton(
onPressed: () { // onPressed: () {
if (_isEditing) { // if (_isEditing) {
_saveChanges(); // _saveChanges();
} else { // } else {
_toggleEdit(); // _toggleEdit();
} // }
}, // },
child: Text(_isEditing ? '儲存變更' : '修改資料'), // child: Text(_isEditing ? '儲存變更' : '修改資料'),
style: TextButton.styleFrom( // style: TextButton.styleFrom(
backgroundColor: Color(0xFFF5E3C3), // backgroundColor: Color(0xFFF5E3C3),
textStyle: TextStyle(fontSize: 18), // textStyle: TextStyle(fontSize: 18),
shadowColor: Colors.transparent, // shadowColor: Colors.transparent,
), // ),
), // ),
ElevatedButton( ElevatedButton(
onPressed: _loginOut, onPressed: _loginOut,
child: Text('登出'), child: Text('登出'),