feat: 實作語言切換功能
This commit is contained in:
@@ -1,12 +1,15 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:topic/HomePage.dart';
|
||||||
|
|
||||||
import 'HistoricalRecord.dart';
|
import 'HistoricalRecord.dart';
|
||||||
import 'KnowledgePage.dart';
|
import 'KnowledgePage.dart';
|
||||||
import 'MessagePage.dart';
|
import 'MessagePage.dart';
|
||||||
import 'PersonalInfo.dart';
|
import 'PersonalInfo.dart';
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
class BottomNavBar extends StatelessWidget {
|
class BottomNavBar extends StatefulWidget {
|
||||||
const BottomNavBar({
|
const BottomNavBar({
|
||||||
super.key,
|
super.key,
|
||||||
required this.email,
|
required this.email,
|
||||||
@@ -16,64 +19,86 @@ class BottomNavBar extends StatelessWidget {
|
|||||||
final String email;
|
final String email;
|
||||||
final int initTabIndex;
|
final int initTabIndex;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<BottomNavBar> createState() => _BottomNavBarState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _BottomNavBarState extends State<BottomNavBar> {
|
||||||
List<PersistentTabConfig> _tabs(BuildContext context) => [
|
List<PersistentTabConfig> _tabs(BuildContext context) => [
|
||||||
PersistentTabConfig.noScreen(
|
PersistentTabConfig.noScreen(
|
||||||
item: ItemConfig(
|
item: ItemConfig(
|
||||||
icon: Icon(Icons.home),
|
icon: Icon(Icons.home),
|
||||||
title: "首頁",
|
title: S.of(context).home,
|
||||||
activeForegroundColor: Colors.orange,
|
activeForegroundColor: Colors.orange,
|
||||||
inactiveForegroundColor: Colors.grey,
|
inactiveForegroundColor: Colors.grey,
|
||||||
),
|
),
|
||||||
onPressed: (context) {
|
onPressed: (context) {
|
||||||
Navigator.pop(context); // Now you can use context here
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(builder: (context) => HomePage(email: widget.email)),
|
||||||
|
).then((value) => setState(() {}));
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
PersistentTabConfig(
|
PersistentTabConfig(
|
||||||
screen: HistoricalRecord(
|
screen: HistoricalRecord(
|
||||||
email: email,
|
email: widget.email,
|
||||||
),
|
),
|
||||||
item: ItemConfig(
|
item: ItemConfig(
|
||||||
icon: Icon(Icons.history_edu),
|
icon: Icon(Icons.history_edu),
|
||||||
title: "跌倒紀錄",
|
title: S.of(context).fall_record,
|
||||||
activeForegroundColor: Colors.orange,
|
activeForegroundColor: Colors.orange,
|
||||||
inactiveForegroundColor: Colors.grey,
|
inactiveForegroundColor: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PersistentTabConfig(
|
PersistentTabConfig(
|
||||||
screen: KnowledgePage(
|
screen: KnowledgePage(
|
||||||
email: email,
|
email: widget.email,
|
||||||
),
|
),
|
||||||
item: ItemConfig(
|
item: ItemConfig(
|
||||||
icon: Icon(Icons.lightbulb_outline),
|
icon: Icon(Icons.lightbulb_outline),
|
||||||
title: "知識補充",
|
title: S.of(context).additional_information,
|
||||||
activeForegroundColor: Colors.orange,
|
activeForegroundColor: Colors.orange,
|
||||||
inactiveForegroundColor: Colors.grey,
|
inactiveForegroundColor: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PersistentTabConfig(
|
PersistentTabConfig(
|
||||||
screen: MessagePage(
|
screen: MessagePage(
|
||||||
email: email,
|
email: widget.email,
|
||||||
),
|
),
|
||||||
item: ItemConfig(
|
item: ItemConfig(
|
||||||
icon: Icon(Icons.monitor_outlined),
|
icon: Icon(Icons.monitor_outlined),
|
||||||
title: "切換畫面",
|
title: S.of(context).switch_camera,
|
||||||
activeForegroundColor: Colors.orange,
|
activeForegroundColor: Colors.orange,
|
||||||
inactiveForegroundColor: Colors.grey,
|
inactiveForegroundColor: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
PersistentTabConfig(
|
PersistentTabConfig(
|
||||||
screen: PersonalInfo(
|
screen: PersonalInfo(
|
||||||
email: email,
|
email: widget.email,
|
||||||
),
|
),
|
||||||
item: ItemConfig(
|
item: ItemConfig(
|
||||||
icon: Icon(Icons.person_sharp),
|
icon: Icon(Icons.person_sharp),
|
||||||
title: "個人資料",
|
title: S.of(context).personal_information,
|
||||||
activeForegroundColor: Colors.orange,
|
activeForegroundColor: Colors.orange,
|
||||||
inactiveForegroundColor: Colors.grey,
|
inactiveForegroundColor: Colors.grey,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_setLanguage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _setLanguage() async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String preLanguage = prefs.getString("language") ?? "";
|
||||||
|
Locale locale = preLanguage == "" ? Locale('zh_Hant') : Locale(preLanguage) ;
|
||||||
|
S.load(locale);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PersistentTabView(
|
return PersistentTabView(
|
||||||
@@ -81,7 +106,7 @@ class BottomNavBar extends StatelessWidget {
|
|||||||
navBarBuilder: (navBarConfig) => Style1BottomNavBar(
|
navBarBuilder: (navBarConfig) => Style1BottomNavBar(
|
||||||
navBarConfig: navBarConfig,
|
navBarConfig: navBarConfig,
|
||||||
),
|
),
|
||||||
controller: PersistentTabController(initialIndex: initTabIndex),
|
controller: PersistentTabController(initialIndex: widget.initTabIndex),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import 'package:mysql_client/mysql_client.dart';
|
|||||||
import 'package:video_player/video_player.dart';
|
import 'package:video_player/video_player.dart';
|
||||||
import 'package:better_player_plus/better_player_plus.dart';
|
import 'package:better_player_plus/better_player_plus.dart';
|
||||||
|
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
class HistoricalRecord extends StatefulWidget {
|
class HistoricalRecord extends StatefulWidget {
|
||||||
final String email; // 接收來自上個頁面的 email
|
final String email; // 接收來自上個頁面的 email
|
||||||
HistoricalRecord({required this.email});
|
HistoricalRecord({required this.email});
|
||||||
@@ -65,6 +67,7 @@ class _HistoricalRecordState extends State<HistoricalRecord> {
|
|||||||
_results = fallResult.rows
|
_results = fallResult.rows
|
||||||
.map((row) =>
|
.map((row) =>
|
||||||
{
|
{
|
||||||
|
'跌倒編號': row.colAt(0),
|
||||||
'跌倒時間': row.colAt(1),
|
'跌倒時間': row.colAt(1),
|
||||||
'跌倒原因': row.colAt(2),
|
'跌倒原因': row.colAt(2),
|
||||||
'跌倒地點': row.colAt(6),
|
'跌倒地點': row.colAt(6),
|
||||||
@@ -97,7 +100,7 @@ class _HistoricalRecordState extends State<HistoricalRecord> {
|
|||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'跌倒紀錄',
|
S.of(context).fall_record,
|
||||||
style: TextStyle(fontSize: 24, height: 5),
|
style: TextStyle(fontSize: 24, height: 5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -133,7 +136,7 @@ class _HistoricalRecordState extends State<HistoricalRecord> {
|
|||||||
),
|
),
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
'編號: ${displayIndex}', // 使用倒序顯示編號
|
S.of(context).fall_id(displayIndex), // 使用倒序顯示編號
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
@@ -143,9 +146,11 @@ class _HistoricalRecordState extends State<HistoricalRecord> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'跌倒時間: ${_results[index]['跌倒時間']}\n'
|
S.of(context).fall_detail(
|
||||||
'跌倒原因: ${_results[index]['跌倒原因']}\n'
|
_results[index]['跌倒時間'],
|
||||||
'跌倒地點: ${_results[index]['跌倒地點']}\n',
|
_results[index]['跌倒原因'],
|
||||||
|
_results[index]['跌倒地點'],
|
||||||
|
),
|
||||||
style: TextStyle(fontSize: 16, color: Colors.black), // 統一字體樣式
|
style: TextStyle(fontSize: 16, color: Colors.black), // 統一字體樣式
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -245,18 +250,18 @@ class _FallDetailPageState extends State<FallDetailPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text('詳細資料'),
|
title: Text(S.of(context).fall_detail_title),
|
||||||
),
|
),
|
||||||
body: Padding(
|
body: Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('跌倒時間: ${widget.fallDetail['跌倒時間']}', style: TextStyle(fontSize: 18)),
|
Text(S.of(context).fall_detail_time(widget.fallDetail['跌倒時間']), style: TextStyle(fontSize: 18)),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Text('跌倒原因: ${widget.fallDetail['跌倒原因']}', style: TextStyle(fontSize: 18)),
|
Text(S.of(context).fall_detail_reason(widget.fallDetail['跌倒原因']), style: TextStyle(fontSize: 18)),
|
||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
Text('跌倒地點: ${widget.fallDetail['跌倒地點']}', style: TextStyle(fontSize: 18)),
|
Text(S.of(context).fall_detail_location(widget.fallDetail['跌倒地點']), style: TextStyle(fontSize: 18)),
|
||||||
if (fhvideoId != '') AspectRatio(
|
if (fhvideoId != '') AspectRatio(
|
||||||
aspectRatio: 16 / 9,
|
aspectRatio: 16 / 9,
|
||||||
child: BetterPlayer(controller: _betterPlayerController),
|
child: BetterPlayer(controller: _betterPlayerController),
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
import 'BottomNavBar.dart';
|
import 'BottomNavBar.dart';
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
final String email;
|
final String email;
|
||||||
@@ -18,6 +20,13 @@ class _HomePageState extends State<HomePage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
// _setLanguage();
|
||||||
|
}
|
||||||
|
void _setLanguage() async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String preLanguage = prefs.getString("language") ?? "";
|
||||||
|
Locale locale = preLanguage == "" ? Locale(preLanguage) : Localizations.localeOf(context);
|
||||||
|
S.load(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -88,7 +97,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'即時畫面',
|
S.of(context).realtime_video,
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -101,10 +110,10 @@ class _HomePageState extends State<HomePage> {
|
|||||||
physics: NeverScrollableScrollPhysics(),
|
physics: NeverScrollableScrollPhysics(),
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
children: [
|
children: [
|
||||||
_buildGridItem(Icons.history_edu, '跌倒紀錄', context),
|
_buildGridItem(Icons.history_edu, S.of(context).fall_record, context),
|
||||||
_buildGridItem(Icons.lightbulb_outline, '知識補充', context),
|
_buildGridItem(Icons.lightbulb_outline, S.of(context).additional_information, context),
|
||||||
_buildGridItem(Icons.monitor_outlined, '切換畫面', context),
|
_buildGridItem(Icons.monitor_outlined, S.of(context).switch_camera, context),
|
||||||
_buildGridItem(Icons.person_sharp, '個人資料', context),
|
_buildGridItem(Icons.person_sharp, S.of(context).personal_information, context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -124,7 +133,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (label == '跌倒紀錄') {
|
if (label == S.of(context).fall_record) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@@ -133,7 +142,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
initTabIndex: 1,
|
initTabIndex: 1,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
} else if (label == '知識補充') {
|
} else if (label == S.of(context).additional_information) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@@ -142,7 +151,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
initTabIndex: 2,
|
initTabIndex: 2,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
} else if (label == '切換畫面') {
|
} else if (label == S.of(context).switch_camera) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute
|
MaterialPageRoute
|
||||||
@@ -151,7 +160,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
initTabIndex: 3,
|
initTabIndex: 3,
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
} else if (label == '個人資料') {
|
} else if (label == S.of(context).personal_information) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:topic/HomePage.dart';
|
import 'package:topic/HomePage.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import 'generated/l10n.dart';
|
||||||
/*void main() {
|
/*void main() {
|
||||||
runApp(MaterialApp(
|
runApp(MaterialApp(
|
||||||
home: KnowledgePage(),
|
home: KnowledgePage(),
|
||||||
@@ -27,7 +29,7 @@ class KnowledgePage extends StatelessWidget {
|
|||||||
padding: EdgeInsets.all(10.0),
|
padding: EdgeInsets.all(10.0),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'知識補充',
|
S.of(context).additional_information,
|
||||||
style: TextStyle(fontSize: 24, height: 5),
|
style: TextStyle(fontSize: 24, height: 5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ 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: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';
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
|
|
||||||
class MessagePage extends StatefulWidget {
|
class MessagePage extends StatefulWidget {
|
||||||
final String email; // 接收來自上個頁面的 email
|
final String email; // 接收來自上個頁面的 email
|
||||||
@@ -114,7 +116,7 @@ class _MessagePageState extends State<MessagePage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'即時畫面',
|
S.of(context).realtime_video,
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
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:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import 'package:topic/HomePage.dart';
|
||||||
import 'package:topic/NoSwipeBackRoute.dart';
|
import 'package:topic/NoSwipeBackRoute.dart';
|
||||||
import 'package:topic/main.dart';
|
import 'package:topic/main.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
class PersonalInfo extends StatefulWidget {
|
class PersonalInfo extends StatefulWidget {
|
||||||
final String email; // 接收來自上個頁面的 email
|
final String email; // 接收來自上個頁面的 email
|
||||||
PersonalInfo({required this.email});
|
PersonalInfo({required this.email});
|
||||||
@@ -136,6 +142,11 @@ class _PersonalInfoState extends State<PersonalInfo> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _setLanguage(Locale locale) async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.setString("language", locale.languageCode);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@@ -161,7 +172,7 @@ class _PersonalInfoState extends State<PersonalInfo> {
|
|||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.manage_accounts_outlined),
|
leading: Icon(Icons.manage_accounts_outlined),
|
||||||
title: Text('基本資料', style: TextStyle(fontSize: 18)),
|
title: Text(S.of(context).basic_information_setting, style: TextStyle(fontSize: 18)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
@@ -181,7 +192,7 @@ class _PersonalInfoState extends State<PersonalInfo> {
|
|||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.lock_open_outlined),
|
leading: Icon(Icons.lock_open_outlined),
|
||||||
title: Text('帳號設定', style: TextStyle(fontSize: 18)),
|
title: Text(S.of(context).account_setting, style: TextStyle(fontSize: 18)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
@@ -196,15 +207,69 @@ class _PersonalInfoState extends State<PersonalInfo> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.language_outlined),
|
leading: Icon(Icons.language_outlined),
|
||||||
title: Text('語言設定', style: TextStyle(fontSize: 18)),
|
title: Text(S.of(context).language_setting, style: TextStyle(fontSize: 18)),
|
||||||
onTap: () {},
|
onTap: () {
|
||||||
|
if(S.current.login_button == 'Login'){
|
||||||
|
S.load(Locale('zh_Hant'));
|
||||||
|
_setLanguage(Locale('zh_Hant'));
|
||||||
|
}else{
|
||||||
|
S.load(Locale('en', 'US'));
|
||||||
|
_setLanguage(Locale('en', 'US'));
|
||||||
|
}
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
// Android-specific code
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(S.of(context).language_setting_alert_title),
|
||||||
|
content: Text(S.of(context).language_alert_android),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
|
||||||
|
},
|
||||||
|
child: Text(S.of(context).confirm),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// iOS-specific code
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(S.of(context).language_setting_alert_title),
|
||||||
|
content: Text(S.of(context).language_alert),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
child: Text(S.of(context).cancel),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
// SystemChannels.platform.invokeMethod('SystemNavigator.pop');
|
||||||
|
pushReplacementWithoutNavBar(context, MaterialPageRoute(builder:(context) => HomePage(
|
||||||
|
email: widget.email)),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: Text(S.of(context).confirm),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.local_phone_rounded),
|
leading: Icon(Icons.local_phone_rounded),
|
||||||
title: Text('撥打電話', style: TextStyle(fontSize: 18)),
|
title: Text(S.of(context).call_phone, style: TextStyle(fontSize: 18)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_showDialerDialog(context); // 顯示對話框,確認是否撥打電話
|
_showDialerDialog(context); // 顯示對話框,確認是否撥打電話
|
||||||
},
|
},
|
||||||
@@ -213,7 +278,7 @@ class _PersonalInfoState extends State<PersonalInfo> {
|
|||||||
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: _loginOut,
|
onPressed: _loginOut,
|
||||||
child: Text('登出'),
|
child: Text(S.of(context).logout_button),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: Color(0xFFF5E3C3),
|
backgroundColor: Color(0xFFF5E3C3),
|
||||||
textStyle: TextStyle(fontSize: 18),
|
textStyle: TextStyle(fontSize: 18),
|
||||||
@@ -330,7 +395,7 @@ class _BasicInfoPageState extends State<BasicInfoPage> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),title: Text('基本資料', style: TextStyle(fontSize: 28)),
|
),title: Text(S.of(context).basic_information_setting, style: TextStyle(fontSize: 28)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
},
|
},
|
||||||
),),
|
),),
|
||||||
@@ -339,7 +404,7 @@ class _BasicInfoPageState extends State<BasicInfoPage> {
|
|||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('姓名'),
|
title: Text(S.of(context).name),
|
||||||
subtitle: _isEditing
|
subtitle: _isEditing
|
||||||
? TextField(
|
? TextField(
|
||||||
controller: _realnameController,
|
controller: _realnameController,
|
||||||
@@ -348,7 +413,7 @@ class _BasicInfoPageState extends State<BasicInfoPage> {
|
|||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('手機'),
|
title: Text(S.of(context).phone),
|
||||||
subtitle: _isEditing
|
subtitle: _isEditing
|
||||||
? TextField(
|
? TextField(
|
||||||
controller: _phoneController,
|
controller: _phoneController,
|
||||||
@@ -357,7 +422,7 @@ class _BasicInfoPageState extends State<BasicInfoPage> {
|
|||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('性別'),
|
title: Text(S.of(context).gender),
|
||||||
subtitle: _isEditing
|
subtitle: _isEditing
|
||||||
? TextField(
|
? TextField(
|
||||||
controller: _genderController,
|
controller: _genderController,
|
||||||
@@ -366,7 +431,7 @@ class _BasicInfoPageState extends State<BasicInfoPage> {
|
|||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('地址'),
|
title: Text(S.of(context).address),
|
||||||
subtitle: _isEditing
|
subtitle: _isEditing
|
||||||
? TextField(
|
? TextField(
|
||||||
controller: _addressController,
|
controller: _addressController,
|
||||||
@@ -382,7 +447,7 @@ class _BasicInfoPageState extends State<BasicInfoPage> {
|
|||||||
_toggleEdit();
|
_toggleEdit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(_isEditing ? '儲存變更' : '修改資料'),
|
child: Text(_isEditing ? S.of(context).save : S.of(context).edit),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: Color(0xFFF5E3C3),
|
backgroundColor: Color(0xFFF5E3C3),
|
||||||
textStyle: TextStyle(fontSize: 18),
|
textStyle: TextStyle(fontSize: 18),
|
||||||
@@ -488,7 +553,7 @@ class _AccountPageState extends State<AccountPage> {
|
|||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
title: Text('帳號設定', style: TextStyle(fontSize: 28)),
|
title: Text(S.of(context).account_setting, style: TextStyle(fontSize: 28)),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -498,7 +563,7 @@ class _AccountPageState extends State<AccountPage> {
|
|||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('電子信箱'),
|
title: Text(S.of(context).email),
|
||||||
subtitle: _isEditing
|
subtitle: _isEditing
|
||||||
? TextField(
|
? TextField(
|
||||||
controller: _emailController,
|
controller: _emailController,
|
||||||
@@ -507,7 +572,7 @@ class _AccountPageState extends State<AccountPage> {
|
|||||||
),
|
),
|
||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text('密碼'),
|
title: Text(S.of(context).password_label),
|
||||||
subtitle: _isEditing
|
subtitle: _isEditing
|
||||||
? TextField(
|
? TextField(
|
||||||
controller: _passwordController,
|
controller: _passwordController,
|
||||||
@@ -535,7 +600,7 @@ class _AccountPageState extends State<AccountPage> {
|
|||||||
_toggleEdit();
|
_toggleEdit();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(_isEditing ? '儲存變更' : '修改資料'),
|
child: Text(_isEditing ? S.of(context).save : S.of(context).edit),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: Color(0xFFF5E3C3),
|
backgroundColor: Color(0xFFF5E3C3),
|
||||||
textStyle: TextStyle(fontSize: 18),
|
textStyle: TextStyle(fontSize: 18),
|
||||||
|
|||||||
67
lib/generated/intl/messages_all.dart
Normal file
67
lib/generated/intl/messages_all.dart
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that looks up messages for specific locales by
|
||||||
|
// delegating to the appropriate library.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:implementation_imports, file_names, unnecessary_new
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering
|
||||||
|
// ignore_for_file:argument_type_not_assignable, invalid_assignment
|
||||||
|
// ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:comment_references
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
import 'package:intl/src/intl_helpers.dart';
|
||||||
|
|
||||||
|
import 'messages_en.dart' as messages_en;
|
||||||
|
import 'messages_zh_Hant.dart' as messages_zh_hant;
|
||||||
|
|
||||||
|
typedef Future<dynamic> LibraryLoader();
|
||||||
|
Map<String, LibraryLoader> _deferredLibraries = {
|
||||||
|
'en': () => new SynchronousFuture(null),
|
||||||
|
'zh_Hant': () => new SynchronousFuture(null),
|
||||||
|
};
|
||||||
|
|
||||||
|
MessageLookupByLibrary? _findExact(String localeName) {
|
||||||
|
switch (localeName) {
|
||||||
|
case 'en':
|
||||||
|
return messages_en.messages;
|
||||||
|
case 'zh_Hant':
|
||||||
|
return messages_zh_hant.messages;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// User programs should call this before using [localeName] for messages.
|
||||||
|
Future<bool> initializeMessages(String localeName) {
|
||||||
|
var availableLocale = Intl.verifiedLocale(
|
||||||
|
localeName, (locale) => _deferredLibraries[locale] != null,
|
||||||
|
onFailure: (_) => null);
|
||||||
|
if (availableLocale == null) {
|
||||||
|
return new SynchronousFuture(false);
|
||||||
|
}
|
||||||
|
var lib = _deferredLibraries[availableLocale];
|
||||||
|
lib == null ? new SynchronousFuture(false) : lib();
|
||||||
|
initializeInternalMessageLookup(() => new CompositeMessageLookup());
|
||||||
|
messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor);
|
||||||
|
return new SynchronousFuture(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _messagesExistFor(String locale) {
|
||||||
|
try {
|
||||||
|
return _findExact(locale) != null;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) {
|
||||||
|
var actualLocale =
|
||||||
|
Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null);
|
||||||
|
if (actualLocale == null) return null;
|
||||||
|
return _findExact(actualLocale);
|
||||||
|
}
|
||||||
81
lib/generated/intl/messages_en.dart
Normal file
81
lib/generated/intl/messages_en.dart
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that provides messages for a en locale. All the
|
||||||
|
// messages from the main program should be duplicated here with the same
|
||||||
|
// function name.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||||
|
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||||
|
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
|
||||||
|
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
|
||||||
|
final messages = new MessageLookup();
|
||||||
|
|
||||||
|
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||||
|
|
||||||
|
class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
String get localeName => 'en';
|
||||||
|
|
||||||
|
static String m0(time, reason, location) =>
|
||||||
|
"Time: ${time}\nReason: ${reason},\nLocation: ${location}\n";
|
||||||
|
|
||||||
|
static String m1(location) => "Location: ${location}";
|
||||||
|
|
||||||
|
static String m2(reason) => "Reason: ${reason}";
|
||||||
|
|
||||||
|
static String m3(time) => "Time: ${time}";
|
||||||
|
|
||||||
|
static String m4(displayIndex) => "ID: ${displayIndex}";
|
||||||
|
|
||||||
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
|
"account_setting": MessageLookupByLibrary.simpleMessage("Account"),
|
||||||
|
"additional_information":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Knowledge"),
|
||||||
|
"address": MessageLookupByLibrary.simpleMessage("Address"),
|
||||||
|
"basic_information_setting":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Basic Information"),
|
||||||
|
"call_phone":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Call Emergency Phone"),
|
||||||
|
"cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
|
||||||
|
"confirm": MessageLookupByLibrary.simpleMessage("Confirm"),
|
||||||
|
"edit": MessageLookupByLibrary.simpleMessage("Edit"),
|
||||||
|
"email": MessageLookupByLibrary.simpleMessage("Email"),
|
||||||
|
"email_label": MessageLookupByLibrary.simpleMessage("Email/Username"),
|
||||||
|
"fall_detail": m0,
|
||||||
|
"fall_detail_location": m1,
|
||||||
|
"fall_detail_reason": m2,
|
||||||
|
"fall_detail_time": m3,
|
||||||
|
"fall_detail_title":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Fall Detail"),
|
||||||
|
"fall_id": m4,
|
||||||
|
"fall_record": MessageLookupByLibrary.simpleMessage("Fall Record"),
|
||||||
|
"fall_record_empty":
|
||||||
|
MessageLookupByLibrary.simpleMessage("No fall record"),
|
||||||
|
"forgot_password":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Forgot password"),
|
||||||
|
"gender": MessageLookupByLibrary.simpleMessage("Gender"),
|
||||||
|
"home": MessageLookupByLibrary.simpleMessage("Home"),
|
||||||
|
"language_alert": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Return to the home page to complete the language setting(Confirm to redirect), otherwise some languages will not be updated in real time!"),
|
||||||
|
"language_alert_android": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"Reopen the APP to complete the language setting, otherwise some languages will not be updated in real time!"),
|
||||||
|
"language_setting": MessageLookupByLibrary.simpleMessage("Language"),
|
||||||
|
"language_setting_alert_title":
|
||||||
|
MessageLookupByLibrary.simpleMessage("Language Setting"),
|
||||||
|
"login_button": MessageLookupByLibrary.simpleMessage("Login"),
|
||||||
|
"logout_button": MessageLookupByLibrary.simpleMessage("Logout"),
|
||||||
|
"name": MessageLookupByLibrary.simpleMessage("Name"),
|
||||||
|
"password_label": MessageLookupByLibrary.simpleMessage("Password"),
|
||||||
|
"personal_information": MessageLookupByLibrary.simpleMessage("Profile"),
|
||||||
|
"phone": MessageLookupByLibrary.simpleMessage("Phone Number"),
|
||||||
|
"realtime_video": MessageLookupByLibrary.simpleMessage("Live View"),
|
||||||
|
"register_button": MessageLookupByLibrary.simpleMessage("Register"),
|
||||||
|
"save": MessageLookupByLibrary.simpleMessage("Save"),
|
||||||
|
"switch_camera": MessageLookupByLibrary.simpleMessage("Switch View")
|
||||||
|
};
|
||||||
|
}
|
||||||
76
lib/generated/intl/messages_zh_Hant.dart
Normal file
76
lib/generated/intl/messages_zh_Hant.dart
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||||
|
// This is a library that provides messages for a zh_Hant locale. All the
|
||||||
|
// messages from the main program should be duplicated here with the same
|
||||||
|
// function name.
|
||||||
|
|
||||||
|
// Ignore issues from commonly used lints in this file.
|
||||||
|
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||||
|
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||||
|
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||||
|
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
|
||||||
|
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:intl/message_lookup_by_library.dart';
|
||||||
|
|
||||||
|
final messages = new MessageLookup();
|
||||||
|
|
||||||
|
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||||
|
|
||||||
|
class MessageLookup extends MessageLookupByLibrary {
|
||||||
|
String get localeName => 'zh_Hant';
|
||||||
|
|
||||||
|
static String m0(time, reason, location) =>
|
||||||
|
"跌倒時間: ${time}\n跌倒原因: ${reason},\n跌倒地點: ${location}\n";
|
||||||
|
|
||||||
|
static String m1(location) => "跌倒地點: ${location}";
|
||||||
|
|
||||||
|
static String m2(reason) => "跌倒原因: ${reason}";
|
||||||
|
|
||||||
|
static String m3(time) => "跌倒時間: ${time}";
|
||||||
|
|
||||||
|
static String m4(displayIndex) => "編號: ${displayIndex}";
|
||||||
|
|
||||||
|
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||||
|
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
|
||||||
|
"account_setting": MessageLookupByLibrary.simpleMessage("帳號設定"),
|
||||||
|
"additional_information": MessageLookupByLibrary.simpleMessage("知識補充"),
|
||||||
|
"address": MessageLookupByLibrary.simpleMessage("地址"),
|
||||||
|
"basic_information_setting":
|
||||||
|
MessageLookupByLibrary.simpleMessage("基本資料"),
|
||||||
|
"call_phone": MessageLookupByLibrary.simpleMessage("撥打電話"),
|
||||||
|
"cancel": MessageLookupByLibrary.simpleMessage("取消"),
|
||||||
|
"confirm": MessageLookupByLibrary.simpleMessage("確認"),
|
||||||
|
"edit": MessageLookupByLibrary.simpleMessage("修改資料"),
|
||||||
|
"email": MessageLookupByLibrary.simpleMessage("電子信箱"),
|
||||||
|
"email_label": MessageLookupByLibrary.simpleMessage("電子信箱/帳號"),
|
||||||
|
"fall_detail": m0,
|
||||||
|
"fall_detail_location": m1,
|
||||||
|
"fall_detail_reason": m2,
|
||||||
|
"fall_detail_time": m3,
|
||||||
|
"fall_detail_title": MessageLookupByLibrary.simpleMessage("詳細資料"),
|
||||||
|
"fall_id": m4,
|
||||||
|
"fall_record": MessageLookupByLibrary.simpleMessage("跌倒紀錄"),
|
||||||
|
"fall_record_empty": MessageLookupByLibrary.simpleMessage("尚無跌倒紀錄"),
|
||||||
|
"forgot_password": MessageLookupByLibrary.simpleMessage("忘記密碼"),
|
||||||
|
"gender": MessageLookupByLibrary.simpleMessage("性別"),
|
||||||
|
"home": MessageLookupByLibrary.simpleMessage("首頁"),
|
||||||
|
"language_alert": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"跳轉回首頁以完成語言設定,否則會有部分語言無法即時更新!"),
|
||||||
|
"language_alert_android": MessageLookupByLibrary.simpleMessage(
|
||||||
|
"重新開啟APP以完成語言設定,否則會有部分語言無法即時更新!"),
|
||||||
|
"language_setting": MessageLookupByLibrary.simpleMessage("語言設定"),
|
||||||
|
"language_setting_alert_title":
|
||||||
|
MessageLookupByLibrary.simpleMessage("語言設定"),
|
||||||
|
"login_button": MessageLookupByLibrary.simpleMessage("登入"),
|
||||||
|
"logout_button": MessageLookupByLibrary.simpleMessage("登出"),
|
||||||
|
"name": MessageLookupByLibrary.simpleMessage("姓名"),
|
||||||
|
"password_label": MessageLookupByLibrary.simpleMessage("密碼"),
|
||||||
|
"personal_information": MessageLookupByLibrary.simpleMessage("個人資料"),
|
||||||
|
"phone": MessageLookupByLibrary.simpleMessage("電話"),
|
||||||
|
"realtime_video": MessageLookupByLibrary.simpleMessage("即時畫面"),
|
||||||
|
"register_button": MessageLookupByLibrary.simpleMessage("立即註冊"),
|
||||||
|
"save": MessageLookupByLibrary.simpleMessage("儲存變更"),
|
||||||
|
"switch_camera": MessageLookupByLibrary.simpleMessage("切換畫面")
|
||||||
|
};
|
||||||
|
}
|
||||||
429
lib/generated/l10n.dart
Normal file
429
lib/generated/l10n.dart
Normal file
@@ -0,0 +1,429 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'intl/messages_all.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// Generator: Flutter Intl IDE plugin
|
||||||
|
// Made by Localizely
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// ignore_for_file: non_constant_identifier_names, lines_longer_than_80_chars
|
||||||
|
// ignore_for_file: join_return_with_assignment, prefer_final_in_for_each
|
||||||
|
// ignore_for_file: avoid_redundant_argument_values, avoid_escaping_inner_quotes
|
||||||
|
|
||||||
|
class S {
|
||||||
|
S();
|
||||||
|
|
||||||
|
static S? _current;
|
||||||
|
|
||||||
|
static S get current {
|
||||||
|
assert(_current != null,
|
||||||
|
'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.');
|
||||||
|
return _current!;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const AppLocalizationDelegate delegate = AppLocalizationDelegate();
|
||||||
|
|
||||||
|
static Future<S> load(Locale locale) {
|
||||||
|
final name = (locale.countryCode?.isEmpty ?? false)
|
||||||
|
? locale.languageCode
|
||||||
|
: locale.toString();
|
||||||
|
final localeName = Intl.canonicalizedLocale(name);
|
||||||
|
return initializeMessages(localeName).then((_) {
|
||||||
|
Intl.defaultLocale = localeName;
|
||||||
|
final instance = S();
|
||||||
|
S._current = instance;
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static S of(BuildContext context) {
|
||||||
|
final instance = S.maybeOf(context);
|
||||||
|
assert(instance != null,
|
||||||
|
'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?');
|
||||||
|
return instance!;
|
||||||
|
}
|
||||||
|
|
||||||
|
static S? maybeOf(BuildContext context) {
|
||||||
|
return Localizations.of<S>(context, S);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Email/Username`
|
||||||
|
String get email_label {
|
||||||
|
return Intl.message(
|
||||||
|
'Email/Username',
|
||||||
|
name: 'email_label',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Password`
|
||||||
|
String get password_label {
|
||||||
|
return Intl.message(
|
||||||
|
'Password',
|
||||||
|
name: 'password_label',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Login`
|
||||||
|
String get login_button {
|
||||||
|
return Intl.message(
|
||||||
|
'Login',
|
||||||
|
name: 'login_button',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Logout`
|
||||||
|
String get logout_button {
|
||||||
|
return Intl.message(
|
||||||
|
'Logout',
|
||||||
|
name: 'logout_button',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Register`
|
||||||
|
String get register_button {
|
||||||
|
return Intl.message(
|
||||||
|
'Register',
|
||||||
|
name: 'register_button',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Forgot password`
|
||||||
|
String get forgot_password {
|
||||||
|
return Intl.message(
|
||||||
|
'Forgot password',
|
||||||
|
name: 'forgot_password',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Live View`
|
||||||
|
String get realtime_video {
|
||||||
|
return Intl.message(
|
||||||
|
'Live View',
|
||||||
|
name: 'realtime_video',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Fall Record`
|
||||||
|
String get fall_record {
|
||||||
|
return Intl.message(
|
||||||
|
'Fall Record',
|
||||||
|
name: 'fall_record',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Switch View`
|
||||||
|
String get switch_camera {
|
||||||
|
return Intl.message(
|
||||||
|
'Switch View',
|
||||||
|
name: 'switch_camera',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Knowledge`
|
||||||
|
String get additional_information {
|
||||||
|
return Intl.message(
|
||||||
|
'Knowledge',
|
||||||
|
name: 'additional_information',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Profile`
|
||||||
|
String get personal_information {
|
||||||
|
return Intl.message(
|
||||||
|
'Profile',
|
||||||
|
name: 'personal_information',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Home`
|
||||||
|
String get home {
|
||||||
|
return Intl.message(
|
||||||
|
'Home',
|
||||||
|
name: 'home',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Basic Information`
|
||||||
|
String get basic_information_setting {
|
||||||
|
return Intl.message(
|
||||||
|
'Basic Information',
|
||||||
|
name: 'basic_information_setting',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Account`
|
||||||
|
String get account_setting {
|
||||||
|
return Intl.message(
|
||||||
|
'Account',
|
||||||
|
name: 'account_setting',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Language`
|
||||||
|
String get language_setting {
|
||||||
|
return Intl.message(
|
||||||
|
'Language',
|
||||||
|
name: 'language_setting',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Call Emergency Phone`
|
||||||
|
String get call_phone {
|
||||||
|
return Intl.message(
|
||||||
|
'Call Emergency Phone',
|
||||||
|
name: 'call_phone',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Name`
|
||||||
|
String get name {
|
||||||
|
return Intl.message(
|
||||||
|
'Name',
|
||||||
|
name: 'name',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Phone Number`
|
||||||
|
String get phone {
|
||||||
|
return Intl.message(
|
||||||
|
'Phone Number',
|
||||||
|
name: 'phone',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Gender`
|
||||||
|
String get gender {
|
||||||
|
return Intl.message(
|
||||||
|
'Gender',
|
||||||
|
name: 'gender',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Address`
|
||||||
|
String get address {
|
||||||
|
return Intl.message(
|
||||||
|
'Address',
|
||||||
|
name: 'address',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Edit`
|
||||||
|
String get edit {
|
||||||
|
return Intl.message(
|
||||||
|
'Edit',
|
||||||
|
name: 'edit',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Save`
|
||||||
|
String get save {
|
||||||
|
return Intl.message(
|
||||||
|
'Save',
|
||||||
|
name: 'save',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Email`
|
||||||
|
String get email {
|
||||||
|
return Intl.message(
|
||||||
|
'Email',
|
||||||
|
name: 'email',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `ID: {displayIndex}`
|
||||||
|
String fall_id(Object displayIndex) {
|
||||||
|
return Intl.message(
|
||||||
|
'ID: $displayIndex',
|
||||||
|
name: 'fall_id',
|
||||||
|
desc: '',
|
||||||
|
args: [displayIndex],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Time: {time}\nReason: {reason},\nLocation: {location}\n`
|
||||||
|
String fall_detail(Object time, Object reason, Object location) {
|
||||||
|
return Intl.message(
|
||||||
|
'Time: $time\nReason: $reason,\nLocation: $location\n',
|
||||||
|
name: 'fall_detail',
|
||||||
|
desc: '',
|
||||||
|
args: [time, reason, location],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Fall Detail`
|
||||||
|
String get fall_detail_title {
|
||||||
|
return Intl.message(
|
||||||
|
'Fall Detail',
|
||||||
|
name: 'fall_detail_title',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Reason: {reason}`
|
||||||
|
String fall_detail_reason(Object reason) {
|
||||||
|
return Intl.message(
|
||||||
|
'Reason: $reason',
|
||||||
|
name: 'fall_detail_reason',
|
||||||
|
desc: '',
|
||||||
|
args: [reason],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Location: {location}`
|
||||||
|
String fall_detail_location(Object location) {
|
||||||
|
return Intl.message(
|
||||||
|
'Location: $location',
|
||||||
|
name: 'fall_detail_location',
|
||||||
|
desc: '',
|
||||||
|
args: [location],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Time: {time}`
|
||||||
|
String fall_detail_time(Object time) {
|
||||||
|
return Intl.message(
|
||||||
|
'Time: $time',
|
||||||
|
name: 'fall_detail_time',
|
||||||
|
desc: '',
|
||||||
|
args: [time],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `No fall record`
|
||||||
|
String get fall_record_empty {
|
||||||
|
return Intl.message(
|
||||||
|
'No fall record',
|
||||||
|
name: 'fall_record_empty',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Language Setting`
|
||||||
|
String get language_setting_alert_title {
|
||||||
|
return Intl.message(
|
||||||
|
'Language Setting',
|
||||||
|
name: 'language_setting_alert_title',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Return to the home page to complete the language setting(Confirm to redirect), otherwise some languages will not be updated in real time!`
|
||||||
|
String get language_alert {
|
||||||
|
return Intl.message(
|
||||||
|
'Return to the home page to complete the language setting(Confirm to redirect), otherwise some languages will not be updated in real time!',
|
||||||
|
name: 'language_alert',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Reopen the APP to complete the language setting, otherwise some languages will not be updated in real time!`
|
||||||
|
String get language_alert_android {
|
||||||
|
return Intl.message(
|
||||||
|
'Reopen the APP to complete the language setting, otherwise some languages will not be updated in real time!',
|
||||||
|
name: 'language_alert_android',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Cancel`
|
||||||
|
String get cancel {
|
||||||
|
return Intl.message(
|
||||||
|
'Cancel',
|
||||||
|
name: 'cancel',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// `Confirm`
|
||||||
|
String get confirm {
|
||||||
|
return Intl.message(
|
||||||
|
'Confirm',
|
||||||
|
name: 'confirm',
|
||||||
|
desc: '',
|
||||||
|
args: [],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||||
|
const AppLocalizationDelegate();
|
||||||
|
|
||||||
|
List<Locale> get supportedLocales {
|
||||||
|
return const <Locale>[
|
||||||
|
Locale.fromSubtags(languageCode: 'en'),
|
||||||
|
Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isSupported(Locale locale) => _isSupported(locale);
|
||||||
|
@override
|
||||||
|
Future<S> load(Locale locale) => S.load(locale);
|
||||||
|
@override
|
||||||
|
bool shouldReload(AppLocalizationDelegate old) => false;
|
||||||
|
|
||||||
|
bool _isSupported(Locale locale) {
|
||||||
|
for (var supportedLocale in supportedLocales) {
|
||||||
|
if (supportedLocale.languageCode == locale.languageCode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
lib/l10n/intl_en.arb
Normal file
43
lib/l10n/intl_en.arb
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"email_label": "Email/Username",
|
||||||
|
"password_label": "Password",
|
||||||
|
"login_button": "Login",
|
||||||
|
"logout_button": "Logout",
|
||||||
|
"register_button": "Register",
|
||||||
|
"forgot_password": "Forgot password",
|
||||||
|
"realtime_video": "Live View",
|
||||||
|
"fall_record": "Fall Record",
|
||||||
|
"switch_camera": "Switch View",
|
||||||
|
"additional_information": "Knowledge",
|
||||||
|
"personal_information": "Profile",
|
||||||
|
|
||||||
|
"home": "Home",
|
||||||
|
|
||||||
|
"basic_information_setting": "Basic Information",
|
||||||
|
"account_setting": "Account",
|
||||||
|
"language_setting": "Language",
|
||||||
|
"call_phone": "Call Emergency Phone",
|
||||||
|
|
||||||
|
"name": "Name",
|
||||||
|
"phone" : "Phone Number",
|
||||||
|
"gender": "Gender",
|
||||||
|
"address": "Address",
|
||||||
|
"edit": "Edit",
|
||||||
|
"save": "Save",
|
||||||
|
|
||||||
|
"email": "Email",
|
||||||
|
|
||||||
|
"fall_id": "ID: {displayIndex}",
|
||||||
|
"fall_detail": "Time: {time}\nReason: {reason},\nLocation: {location}\n",
|
||||||
|
"fall_detail_title": "Fall Detail",
|
||||||
|
"fall_detail_reason": "Reason: {reason}",
|
||||||
|
"fall_detail_location": "Location: {location}",
|
||||||
|
"fall_detail_time": "Time: {time}",
|
||||||
|
"fall_record_empty": "No fall record",
|
||||||
|
|
||||||
|
"language_setting_alert_title": "Language Setting",
|
||||||
|
"language_alert": "Return to the home page to complete the language setting(Confirm to redirect), otherwise some languages will not be updated in real time!",
|
||||||
|
"language_alert_android": "Reopen the APP to complete the language setting, otherwise some languages will not be updated in real time!",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"confirm": "Confirm"
|
||||||
|
}
|
||||||
45
lib/l10n/intl_zh_Hant.arb
Normal file
45
lib/l10n/intl_zh_Hant.arb
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"email_label": "電子信箱/帳號",
|
||||||
|
"password_label": "密碼",
|
||||||
|
"login_button": "登入",
|
||||||
|
"logout_button": "登出",
|
||||||
|
"register_button": "立即註冊",
|
||||||
|
"forgot_password": "忘記密碼",
|
||||||
|
|
||||||
|
"realtime_video": "即時畫面",
|
||||||
|
"fall_record": "跌倒紀錄",
|
||||||
|
"switch_camera": "切換畫面",
|
||||||
|
"additional_information": "知識補充",
|
||||||
|
"personal_information": "個人資料",
|
||||||
|
|
||||||
|
"home": "首頁",
|
||||||
|
|
||||||
|
"basic_information_setting": "基本資料",
|
||||||
|
"account_setting": "帳號設定",
|
||||||
|
"language_setting": "語言設定",
|
||||||
|
"call_phone": "撥打電話",
|
||||||
|
|
||||||
|
"name": "姓名",
|
||||||
|
"phone": "電話",
|
||||||
|
"gender": "性別",
|
||||||
|
"address": "地址",
|
||||||
|
"edit": "修改資料",
|
||||||
|
"save": "儲存變更",
|
||||||
|
|
||||||
|
"email": "電子信箱",
|
||||||
|
|
||||||
|
"fall_id": "編號: {displayIndex}",
|
||||||
|
"fall_detail": "跌倒時間: {time}\n跌倒原因: {reason},\n跌倒地點: {location}\n",
|
||||||
|
"fall_detail_title": "詳細資料",
|
||||||
|
"fall_detail_reason": "跌倒原因: {reason}",
|
||||||
|
"fall_detail_location": "跌倒地點: {location}",
|
||||||
|
"fall_detail_time": "跌倒時間: {time}",
|
||||||
|
"fall_record_empty": "尚無跌倒紀錄",
|
||||||
|
|
||||||
|
"language_setting_alert_title": "語言設定",
|
||||||
|
"language_alert": "跳轉回首頁以完成語言設定,否則會有部分語言無法即時更新!",
|
||||||
|
"language_alert_android": "重新開啟APP以完成語言設定,否則會有部分語言無法即時更新!",
|
||||||
|
"cancel": "取消",
|
||||||
|
"confirm": "確認"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:topic/HomePage.dart';
|
import 'package:topic/HomePage.dart';
|
||||||
import 'package:mysql_client/mysql_client.dart';
|
import 'package:mysql_client/mysql_client.dart';
|
||||||
@@ -8,11 +11,23 @@ import 'package:topic/RegisterPage.dart';
|
|||||||
import 'package:topic/ForgetPasswordPage.dart';
|
import 'package:topic/ForgetPasswordPage.dart';
|
||||||
import 'package:validators/validators.dart' as validator;
|
import 'package:validators/validators.dart' as validator;
|
||||||
|
|
||||||
|
import 'generated/l10n.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
runApp(MaterialApp(
|
runApp(
|
||||||
home: LoginPage(),
|
MaterialApp(
|
||||||
));
|
localizationsDelegates: [
|
||||||
|
S.delegate,
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
], //add
|
||||||
|
supportedLocales: S.delegate.supportedLocales, // add
|
||||||
|
home: LoginPage(),
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
@@ -28,6 +43,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
//初始化
|
//初始化
|
||||||
|
_setLanguage(); //設定語言
|
||||||
super.initState();
|
super.initState();
|
||||||
_fetchData(); //連資料庫
|
_fetchData(); //連資料庫
|
||||||
_CheckPreLoginInfo(); //確定有先前有無登入
|
_CheckPreLoginInfo(); //確定有先前有無登入
|
||||||
@@ -66,6 +82,14 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _setLanguage() async {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
String preLanguage = prefs.getString("language") ?? "";
|
||||||
|
Locale locale = preLanguage == "" ? Localizations.localeOf(context) : Locale(preLanguage);
|
||||||
|
S.load(locale);
|
||||||
|
setState(() {});
|
||||||
|
}
|
||||||
|
|
||||||
void _setLoginInfo(String email) async {
|
void _setLoginInfo(String email) async {
|
||||||
//save user email into share preference to let app can auto login next open
|
//save user email into share preference to let app can auto login next open
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
@@ -176,7 +200,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
prefixIcon: Icon(Icons.email_outlined),
|
prefixIcon: Icon(Icons.email_outlined),
|
||||||
//https://www.fluttericon.cn/v
|
//https://www.fluttericon.cn/v
|
||||||
labelText: '電子信箱/帳號',
|
labelText: S.of(context).email_label,
|
||||||
),
|
),
|
||||||
), //電子信箱
|
), //電子信箱
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
@@ -197,7 +221,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
labelText: '密碼',
|
labelText: S.of(context).password_label,
|
||||||
),
|
),
|
||||||
obscureText: _passwordNotVisible,
|
obscureText: _passwordNotVisible,
|
||||||
), //密碼
|
), //密碼
|
||||||
@@ -210,7 +234,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
MaterialPageRoute(builder: (context) => HomePage()),
|
MaterialPageRoute(builder: (context) => HomePage()),
|
||||||
);
|
);
|
||||||
},*/
|
},*/
|
||||||
child: Text(' 登入'),
|
child: Text(S.of(context).login_button),
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Color(0xFF4FC3F7),
|
backgroundColor: Color(0xFF4FC3F7),
|
||||||
padding:
|
padding:
|
||||||
@@ -227,7 +251,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
builder: (context) => RegisterPage()),
|
builder: (context) => RegisterPage()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text('立即註冊'),
|
child: Text(S.of(context).register_button),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
// TODO: In physical devices, the background color of the button is transparent
|
// TODO: In physical devices, the background color of the button is transparent
|
||||||
backgroundColor: Colors.transparent, // 無背景颜色
|
backgroundColor: Colors.transparent, // 無背景颜色
|
||||||
@@ -243,7 +267,7 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
builder: (context) => ForgetPasswordPage()),
|
builder: (context) => ForgetPasswordPage()),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
child: Text('忘記密碼'),
|
child: Text(S.of(context).forgot_password),
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
backgroundColor: Colors.transparent, // 無背景颜色
|
backgroundColor: Colors.transparent, // 無背景颜色
|
||||||
textStyle: TextStyle(fontSize: 18),
|
textStyle: TextStyle(fontSize: 18),
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
mysql_client: ^0.0.27
|
mysql_client: ^0.0.27
|
||||||
url_launcher: ^6.0.10
|
url_launcher: ^6.0.10
|
||||||
|
|
||||||
@@ -103,3 +105,5 @@ flutter:
|
|||||||
#
|
#
|
||||||
# For details regarding fonts from package dependencies,
|
# For details regarding fonts from package dependencies,
|
||||||
# see https://flutter.dev/custom-fonts/#from-packages
|
# see https://flutter.dev/custom-fonts/#from-packages
|
||||||
|
flutter_intl:
|
||||||
|
enabled: true
|
||||||
|
|||||||
Reference in New Issue
Block a user