Skip to content
This repository has been archived by the owner on Apr 25, 2022. It is now read-only.

Commit

Permalink
Merge pull request #105 from CCXXXI/dev
Browse files Browse the repository at this point in the history
v0.6.0
  • Loading branch information
CCXXXI authored Oct 3, 2021
2 parents 856b2bc + bb11320 commit 9376c88
Show file tree
Hide file tree
Showing 17 changed files with 469 additions and 33 deletions.
7 changes: 7 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
package="io.github.ccxxxi.ecnu_timetable">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<queries>
<!-- If your app opens https URLs -->
<intent>
<action android:name="android.intent.action.VIEW"/>
<data android:scheme="https"/>
</intent>
</queries>
<application
android:label="ECNU Timetable"
android:icon="@mipmap/ic_launcher">
Expand Down
1 change: 1 addition & 0 deletions dart_dependency_validator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ ignore:
- flutter_web_plugins
- package_info_plus_web
- shared_preferences_web
- url_launcher_web
4 changes: 2 additions & 2 deletions lib/home/home_logic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:get/get.dart';

import '../utils/gu.dart';
import '../secret/secret_view.dart';
import '../utils/logger.dart';

class HomeLogic extends GetxController {
Expand Down Expand Up @@ -46,7 +46,7 @@ class HomeLogic extends GetxController {
if (isAnimating.isFalse) idx.value = idx_;
}

void ecnuLongPress() => gu(); // todo
void ecnuLongPress() => Get.to(SecretPage());
}

// NavigationRail: Timetable, Toolbox, Settings
Expand Down
2 changes: 1 addition & 1 deletion lib/home/home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class HomePage extends StatelessWidget {
? AppBar(
title: const Text(
'求实创造 为人师表',
style: TextStyle(fontFamily: fontSerif),
style: TextStyle(fontFamily: notoSerif),
),
leading: ecnuButton(),
)
Expand Down
1 change: 1 addition & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Future<void> main() async {
initLogger();
await Settings.init();
if (GetPlatform.isDesktop && !GetPlatform.isWeb) initDesktop();
await initMessages();
await initSentry(const MyApp());
}

Expand Down
7 changes: 7 additions & 0 deletions lib/secret/secret_logic.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import 'package:get/get.dart';

import 'trivia_view.dart';

class SecretLogic extends GetxController {
void triviaOnTap() => Get.to(const TriviaPage());
}
25 changes: 25 additions & 0 deletions lib/secret/secret_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import 'secret_logic.dart';

class SecretPage extends StatelessWidget {
SecretPage({Key? key}) : super(key: key);

final logic = Get.put(SecretLogic());

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
ListTile(
title: const Text('Trivia'),
onTap: logic.triviaOnTap,
)
],
),
);
}
}
15 changes: 15 additions & 0 deletions lib/secret/trivia_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import 'package:flutter/material.dart';

import '../settings/trivia.dart';

class TriviaPage extends StatelessWidget {
const TriviaPage({Key? key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(itemBuilder: (_, idx) => getTrivia(idx)),
);
}
}
49 changes: 49 additions & 0 deletions lib/settings/settings_logic.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import 'package:dio/dio.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:get/get.dart';
import 'package:url_launcher/url_launcher.dart';

import '../utils/gu.dart';
import '../utils/logger.dart';
import '../utils/messages.dart';
import 'theme.dart' as theme;

class SettingsLogic extends GetxController {
Expand All @@ -14,4 +18,49 @@ class SettingsLogic extends GetxController {
void login() => gu(); // todo

void updateTheme(_) => theme.updateTheme();

/// - null: loading
/// - empty: failed
final latestVer = Rx<String?>(null);

@override
Future<void> onInit() async {
super.onInit();
updateVerInfo();
}

void updateVerInfo() async {
latestVer.value = null;
latestVer.value = await _getLatestVer() ?? '';
if (updateAvailable) {
Get.snackbar('发现新版本', '$version → ${latestVer.value}');
}
}

bool get updateAvailable => latestVer.value != version;

/// Get latest release version from GitHub.
Future<String?> _getLatestVer() async {
try {
final r = await Dio().get(
'https://api.github.com/repos/ccxxxi/ecnu_timetable/releases',
queryParameters: {'per_page': 1},
);
return (r.data[0]['name'] as String).substring(1);
} catch (e) {
logger.e(e);
Get.snackbar('获取最新版本失败', e.toString());
}
}

static String _getVerUrl(String v) =>
'https://github.com/CCXXXI/ecnu_timetable/releases/tag/v$v';

Future<void> curVerOnTap() async => await launch(_getVerUrl(version));

Future<void> latestVerOnTap() async =>
await launch(_getVerUrl(latestVer.value!));

Future<void> feedbackOnTap() async =>
await launch('https://github.com/CCXXXI/ecnu_timetable/issues');
}
86 changes: 76 additions & 10 deletions lib/settings/settings_view.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';

import '../utils/loading.dart';
import '../utils/messages.dart';
import 'settings_logic.dart';
import 'theme.dart';
import 'trivia.dart';

class SettingsPage extends StatelessWidget {
SettingsPage({Key? key}) : super(key: key);
Expand All @@ -16,15 +19,20 @@ class SettingsPage extends StatelessWidget {
Widget build(BuildContext context) {
return ListView(
children: [
user(),
user,
const Divider(),
SettingsGroup(title: '主题', children: [dark(), font(), color()]),
SettingsGroup(title: '杂项', children: [launchPage()]),
SettingsGroup(title: '主题', children: [dark, font, color]),
SettingsGroup(title: '杂项', children: [launchPage]),
SettingsGroup(
title: '关于', children: [curVer, latestVer, feedback, licenses]),
const Divider(),
trivia,
],
);
}

Widget user() => logic.loggedIn
// region user
Widget get user => logic.loggedIn
? ListTile(
leading: const Icon(Icons.person),
trailing: const Icon(Icons.logout),
Expand All @@ -39,8 +47,10 @@ class SettingsPage extends StatelessWidget {
onTap: logic.login,
);

// endregion

// region theme
Widget dark() => DropDownSettingsTile(
Widget get dark => DropDownSettingsTile(
title: '深色模式',
settingKey: 'themeMode',
values: {
Expand All @@ -52,15 +62,15 @@ class SettingsPage extends StatelessWidget {
onChange: logic.updateTheme,
);

Widget font() => SimpleDropDownSettingsTile(
Widget get font => DropDownSettingsTile(
title: '字体',
settingKey: 'font',
values: const [fontSans, fontSerif],
selected: fontSans,
values: fonts,
selected: notoSans,
onChange: logic.updateTheme,
);

Widget color() => SwitchSettingsTile(
Widget get color => SwitchSettingsTile(
title: '自定义',
settingKey: 'overrideColor',
onChange: logic.updateTheme,
Expand All @@ -78,7 +88,7 @@ class SettingsPage extends StatelessWidget {
//endregion

// region misc
Widget launchPage() => DropDownSettingsTile(
Widget get launchPage => DropDownSettingsTile(
title: '启动页',
settingKey: 'launchPage',
values: const {
Expand All @@ -90,4 +100,60 @@ class SettingsPage extends StatelessWidget {
);

// endregion

// region about
Widget get curVer => ListTile(
title: const Text('当前版本'),
trailing: const Text(version),
onTap: logic.curVerOnTap,
);

Widget get latestVer => Obx(() => ListTile(
title: const Text('最新版本'),
trailing: logic.latestVer.value == null
? Loading()
: logic.latestVer.value!.isEmpty
? IconButton(
onPressed: logic.updateVerInfo,
icon: const Icon(Icons.refresh),
)
: Badge(
child: Text(logic.latestVer.value!),
badgeContent: Icon(
logic.updateAvailable
? Icons.new_releases_outlined
: Icons.check,
size: 20,
),
padding: EdgeInsets.zero,
badgeColor:
logic.updateAvailable ? Colors.red : Colors.green,
position: BadgePosition.topEnd(top: -16, end: -16),
),
onTap: logic.latestVerOnTap,
enabled: logic.latestVer.value?.isNotEmpty ?? false,
));

Widget get feedback => ListTile(
title: const Text('反馈'),
trailing: const FaIcon(FontAwesomeIcons.github),
onTap: logic.feedbackOnTap,
);

Widget get licenses => AboutListTile(
applicationIcon: const Image(
image: AssetImage('assets/images/app_icon.png'),
height: 42,
),
applicationLegalese: license,
applicationVersion: release,
child: const Text('许可协议'),
);

// endregion

Widget get trivia => ListTile(
leading: const Icon(Icons.lightbulb),
title: randomTrivia,
);
}
58 changes: 49 additions & 9 deletions lib/settings/theme.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:get/get.dart';
import 'package:google_fonts/google_fonts.dart';

import '../utils/logger.dart';
import '../utils/messages.dart';

// region colorScheme
const _ecnuColorStr = '#ffa41f35';
final ecnuColor = ConversionUtils.colorFromString(_ecnuColorStr);

Expand All @@ -19,16 +22,53 @@ Color _c(String key) => Settings.getValue('overrideColor', false)
Settings.getValue('color.$key', _ecnuColorStr))
: ecnuColor;

ThemeData get theme => ThemeData.from(
colorScheme: (_dark ? ColorScheme.dark : ColorScheme.light)(
primary: _c('primary'),
secondary: _c('secondary'),
surface: _c('surface'),
),
textTheme: (_dark ? ThemeData.dark : ThemeData.light)()
.textTheme
.apply(fontFamily: Settings.getValue('font', fontSans)),
ColorScheme get _colorScheme => (_dark ? ColorScheme.dark : ColorScheme.light)(
primary: _c('primary'),
secondary: _c('secondary'),
surface: _c('surface'),
);
// endregion

// region textTheme
const _localFonts = {
notoSans: '思源黑体',
notoSerif: '思源宋体',
};
const _googleFonts = {
'ZCOOL QingKe HuangYou': '站酷黄油',
'ZCOOL XiaoWei': '站酷小薇',
'ZCOOL KuaiLe': '站酷快乐',
'Ma Shan Zheng': '钟齐善政',
'Zhi Mang Xing': '钟齐志莽',
'Liu Jian Mao Cao': '钟齐流江',
'Long Cang': '有字龙藏',
};

const fonts = {'': '跟随系统', ..._localFonts, ..._googleFonts};

TextTheme get _baseTextTheme =>
(_dark ? ThemeData.dark : ThemeData.light)().textTheme;

String get _font => Settings.getValue('font', notoSans);

TextTheme get _textTheme {
if (_localFonts.containsKey(_font)) {
logger.i('_localFonts.containsKey($_font)');
return _baseTextTheme.apply(fontFamily: _font);
}

if (_googleFonts.containsKey(_font)) {
logger.i('_googleFonts.containsKey($_font)');
return GoogleFonts.getTextTheme(_font, _baseTextTheme);
}

logger.i('No font named "$_font", return _baseTextTheme.');
return _baseTextTheme;
}
// endregion

ThemeData get theme =>
ThemeData.from(colorScheme: _colorScheme, textTheme: _textTheme);

// void updateTheme() => Get.changeTheme(theme);
// todo: wait for https://github.com/jonataslaw/getx/issues/1878
Expand Down
Loading

0 comments on commit 9376c88

Please sign in to comment.