mirror of
https://github.com/Livinglist/Hacki.git
synced 2025-08-06 18:24:42 +08:00
Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
6a8022e177 | |||
4626b6f45b | |||
674c67a317 |
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# <img width="64" src="https://user-images.githubusercontent.com/7277662/167775086-0b234f28-dee4-44f6-aae4-14a28ed4bbb6.png"> Hacki for Hacker News
|
# <img width="64" src="https://user-images.githubusercontent.com/7277662/167775086-0b234f28-dee4-44f6-aae4-14a28ed4bbb6.png"> Hacki for Hacker News
|
||||||
|
|
||||||
A simple noiseless Hacker News reader made with Flutter that is just enough.
|
A simple noiseless [Hacker News](https://news.ycombinator.com/) reader made with Flutter that is just enough.
|
||||||
|
|
||||||
[](https://apps.apple.com/us/app/hacki/id1602043763)
|
[](https://apps.apple.com/us/app/hacki/id1602043763)
|
||||||
[](https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US)
|
[](https://play.google.com/store/apps/details?id=com.jiaqifeng.hacki&hl=en_US&gl=US)
|
||||||
|
4
fastlane/metadata/android/en-US/changelogs/40.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/40.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
- You can now participate in polls.
|
||||||
|
- Pick up where you left off.
|
||||||
|
- Swipe left on comment tile to view its parents without scrolling all the way up.
|
||||||
|
- Huge performance boost.
|
@ -367,7 +367,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 11;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = QMWX3X2NF7;
|
DEVELOPMENT_TEAM = QMWX3X2NF7;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -376,7 +376,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.2.5;
|
MARKETING_VERSION = 0.2.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -503,7 +503,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 11;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = QMWX3X2NF7;
|
DEVELOPMENT_TEAM = QMWX3X2NF7;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -512,7 +512,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.2.5;
|
MARKETING_VERSION = 0.2.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -533,7 +533,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 11;
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
DEVELOPMENT_TEAM = QMWX3X2NF7;
|
DEVELOPMENT_TEAM = QMWX3X2NF7;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -542,7 +542,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 0.2.5;
|
MARKETING_VERSION = 0.2.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
|
PRODUCT_BUNDLE_IDENTIFIER = com.jiaqi.hacki;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
@ -4,17 +4,20 @@ import 'dart:io';
|
|||||||
import 'package:adaptive_theme/adaptive_theme.dart';
|
import 'package:adaptive_theme/adaptive_theme.dart';
|
||||||
import 'package:feature_discovery/feature_discovery.dart';
|
import 'package:feature_discovery/feature_discovery.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||||
import 'package:hacki/blocs/blocs.dart';
|
import 'package:hacki/blocs/blocs.dart';
|
||||||
import 'package:hacki/config/custom_router.dart';
|
import 'package:hacki/config/custom_router.dart';
|
||||||
import 'package:hacki/config/locator.dart';
|
import 'package:hacki/config/locator.dart';
|
||||||
import 'package:hacki/cubits/cubits.dart';
|
import 'package:hacki/cubits/cubits.dart';
|
||||||
|
import 'package:hacki/repositories/repositories.dart' show PreferenceRepository;
|
||||||
import 'package:hacki/screens/screens.dart';
|
import 'package:hacki/screens/screens.dart';
|
||||||
import 'package:hacki/services/fetcher.dart';
|
import 'package:hacki/services/fetcher.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:rxdart/rxdart.dart' show BehaviorSubject;
|
import 'package:rxdart/rxdart.dart' show BehaviorSubject;
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:workmanager/workmanager.dart';
|
import 'package:workmanager/workmanager.dart';
|
||||||
|
|
||||||
// For receiving payload event from local notifications.
|
// For receiving payload event from local notifications.
|
||||||
@ -63,6 +66,9 @@ Future<void> main() async {
|
|||||||
await setUpLocator();
|
await setUpLocator();
|
||||||
|
|
||||||
final AdaptiveThemeMode? savedThemeMode = await AdaptiveTheme.getThemeMode();
|
final AdaptiveThemeMode? savedThemeMode = await AdaptiveTheme.getThemeMode();
|
||||||
|
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
final bool trueDarkMode =
|
||||||
|
prefs.getBool(PreferenceRepository.trueDarkModeKey) ?? false;
|
||||||
|
|
||||||
// Uncomment code below for running with logging.
|
// Uncomment code below for running with logging.
|
||||||
// BlocOverrides.runZoned(
|
// BlocOverrides.runZoned(
|
||||||
@ -79,6 +85,7 @@ Future<void> main() async {
|
|||||||
runApp(
|
runApp(
|
||||||
HackiApp(
|
HackiApp(
|
||||||
savedThemeMode: savedThemeMode,
|
savedThemeMode: savedThemeMode,
|
||||||
|
trueDarkMode: trueDarkMode,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -87,9 +94,11 @@ class HackiApp extends StatelessWidget {
|
|||||||
const HackiApp({
|
const HackiApp({
|
||||||
super.key,
|
super.key,
|
||||||
this.savedThemeMode,
|
this.savedThemeMode,
|
||||||
|
required this.trueDarkMode,
|
||||||
});
|
});
|
||||||
|
|
||||||
final AdaptiveThemeMode? savedThemeMode;
|
final AdaptiveThemeMode? savedThemeMode;
|
||||||
|
final bool trueDarkMode;
|
||||||
|
|
||||||
static final GlobalKey<NavigatorState> navigatorKey =
|
static final GlobalKey<NavigatorState> navigatorKey =
|
||||||
GlobalKey<NavigatorState>();
|
GlobalKey<NavigatorState>();
|
||||||
@ -166,6 +175,7 @@ class HackiApp extends StatelessWidget {
|
|||||||
dark: ThemeData(
|
dark: ThemeData(
|
||||||
brightness: Brightness.dark,
|
brightness: Brightness.dark,
|
||||||
primarySwatch: Colors.orange,
|
primarySwatch: Colors.orange,
|
||||||
|
canvasColor: trueDarkMode ? Colors.black : null,
|
||||||
),
|
),
|
||||||
initial: savedThemeMode ?? AdaptiveThemeMode.system,
|
initial: savedThemeMode ?? AdaptiveThemeMode.system,
|
||||||
builder: (ThemeData theme, ThemeData darkTheme) {
|
builder: (ThemeData theme, ThemeData darkTheme) {
|
||||||
@ -174,16 +184,29 @@ class HackiApp extends StatelessWidget {
|
|||||||
primarySwatch: Colors.orange,
|
primarySwatch: Colors.orange,
|
||||||
canvasColor: Colors.black,
|
canvasColor: Colors.black,
|
||||||
);
|
);
|
||||||
|
return FutureBuilder<AdaptiveThemeMode?>(
|
||||||
|
future: AdaptiveTheme.getThemeMode(),
|
||||||
|
builder: (
|
||||||
|
BuildContext context,
|
||||||
|
AsyncSnapshot<AdaptiveThemeMode?> snapshot,
|
||||||
|
) {
|
||||||
|
final AdaptiveThemeMode? mode = snapshot.data;
|
||||||
return BlocBuilder<PreferenceCubit, PreferenceState>(
|
return BlocBuilder<PreferenceCubit, PreferenceState>(
|
||||||
buildWhen: (PreferenceState previous, PreferenceState current) =>
|
buildWhen:
|
||||||
|
(PreferenceState previous, PreferenceState current) =>
|
||||||
previous.useTrueDark != current.useTrueDark,
|
previous.useTrueDark != current.useTrueDark,
|
||||||
builder: (BuildContext context, PreferenceState prefState) {
|
builder: (BuildContext context, PreferenceState prefState) {
|
||||||
|
final bool useTrueDark = prefState.useTrueDark &&
|
||||||
|
(mode == AdaptiveThemeMode.dark ||
|
||||||
|
(mode == AdaptiveThemeMode.system &&
|
||||||
|
SchedulerBinding
|
||||||
|
.instance.window.platformBrightness ==
|
||||||
|
Brightness.dark));
|
||||||
return FeatureDiscovery(
|
return FeatureDiscovery(
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
title: 'Hacki',
|
title: 'Hacki',
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
theme: prefState.useTrueDark ? trueDarkTheme : theme,
|
theme: useTrueDark ? trueDarkTheme : theme,
|
||||||
darkTheme: prefState.useTrueDark ? trueDarkTheme : darkTheme,
|
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
onGenerateRoute: CustomRouter.onGenerateRoute,
|
onGenerateRoute: CustomRouter.onGenerateRoute,
|
||||||
initialRoute: HomeScreen.routeName,
|
initialRoute: HomeScreen.routeName,
|
||||||
@ -192,6 +215,8 @@ class HackiApp extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,11 @@ class PreferenceRepository {
|
|||||||
static const String _lastReadStoryIdKey = 'lastReadStoryId';
|
static const String _lastReadStoryIdKey = 'lastReadStoryId';
|
||||||
|
|
||||||
static const String _notificationModeKey = 'notificationMode';
|
static const String _notificationModeKey = 'notificationMode';
|
||||||
static const String _trueDarkModeKey = 'trueDarkMode';
|
|
||||||
static const String _readerModeKey = 'readerMode';
|
static const String _readerModeKey = 'readerMode';
|
||||||
|
|
||||||
|
/// Exposing this val for main func.
|
||||||
|
static const String trueDarkModeKey = 'trueDarkMode';
|
||||||
|
|
||||||
/// The key of a boolean value deciding whether or not the story
|
/// The key of a boolean value deciding whether or not the story
|
||||||
/// tile should display link preview. Defaults to true.
|
/// tile should display link preview. Defaults to true.
|
||||||
static const String _displayModeKey = 'displayMode';
|
static const String _displayModeKey = 'displayMode';
|
||||||
@ -99,7 +101,7 @@ class PreferenceRepository {
|
|||||||
|
|
||||||
Future<bool> get trueDarkMode async => _prefs.then(
|
Future<bool> get trueDarkMode async => _prefs.then(
|
||||||
(SharedPreferences prefs) =>
|
(SharedPreferences prefs) =>
|
||||||
prefs.getBool(_trueDarkModeKey) ?? _trueDarkModeDefaultValue,
|
prefs.getBool(trueDarkModeKey) ?? _trueDarkModeDefaultValue,
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<bool> get readerMode async => _prefs.then(
|
Future<bool> get readerMode async => _prefs.then(
|
||||||
@ -247,8 +249,8 @@ class PreferenceRepository {
|
|||||||
Future<void> toggleTrueDarkMode() async {
|
Future<void> toggleTrueDarkMode() async {
|
||||||
final SharedPreferences prefs = await _prefs;
|
final SharedPreferences prefs = await _prefs;
|
||||||
final bool currentMode =
|
final bool currentMode =
|
||||||
prefs.getBool(_trueDarkModeKey) ?? _trueDarkModeDefaultValue;
|
prefs.getBool(trueDarkModeKey) ?? _trueDarkModeDefaultValue;
|
||||||
await prefs.setBool(_trueDarkModeKey, !currentMode);
|
await prefs.setBool(trueDarkModeKey, !currentMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> toggleReaderMode() async {
|
Future<void> toggleReaderMode() async {
|
||||||
|
@ -372,6 +372,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> onFeatureDiscoveryDismissed() {
|
Future<bool> onFeatureDiscoveryDismissed() {
|
||||||
|
HapticFeedback.lightImpact();
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
ScaffoldMessenger.of(context).clearSnackBars();
|
||||||
showSnackBar(content: 'Tap on icon to continue');
|
showSnackBar(content: 'Tap on icon to continue');
|
||||||
return Future<bool>.value(false);
|
return Future<bool>.value(false);
|
||||||
@ -383,7 +384,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
final bool useReader = context.read<PreferenceCubit>().state.useReader;
|
final bool useReader = context.read<PreferenceCubit>().state.useReader;
|
||||||
final bool offlineReading =
|
final bool offlineReading =
|
||||||
context.read<StoriesBloc>().state.offlineReading;
|
context.read<StoriesBloc>().state.offlineReading;
|
||||||
final bool firstTimeReading = cacheService.isFirstTimeReading(story.id);
|
final bool hasRead = context.read<StoriesBloc>().hasRead(story);
|
||||||
final bool splitViewEnabled = context.read<SplitViewCubit>().state.enabled;
|
final bool splitViewEnabled = context.read<SplitViewCubit>().state.enabled;
|
||||||
|
|
||||||
// If a story is a job story and it has a link to the job posting,
|
// If a story is a job story and it has a link to the job posting,
|
||||||
@ -411,8 +412,7 @@ class _HomeScreenState extends State<HomeScreen>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!offlineReading &&
|
if (!offlineReading && (isJobWithLink || (showWebFirst && !hasRead))) {
|
||||||
(isJobWithLink || (showWebFirst && firstTimeReading))) {
|
|
||||||
LinkUtil.launchUrl(story.url, useReader: useReader);
|
LinkUtil.launchUrl(story.url, useReader: useReader);
|
||||||
cacheService.store(story.id);
|
cacheService.store(story.id);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,9 @@ class _ProfileScreenState extends State<ProfileScreen>
|
|||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: const Text('True Dark Mode'),
|
title: const Text('True Dark Mode'),
|
||||||
subtitle: const Text('real dark.'),
|
subtitle: const Text(
|
||||||
|
'you might need to restart the app.',
|
||||||
|
),
|
||||||
value: preferenceState.useTrueDark,
|
value: preferenceState.useTrueDark,
|
||||||
onChanged: (bool val) {
|
onChanged: (bool val) {
|
||||||
HapticFeedback.lightImpact();
|
HapticFeedback.lightImpact();
|
||||||
@ -368,17 +370,10 @@ class _ProfileScreenState extends State<ProfileScreen>
|
|||||||
activeColor: Colors.orange,
|
activeColor: Colors.orange,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: const Text(
|
||||||
'Theme',
|
'Theme',
|
||||||
style: TextStyle(
|
|
||||||
decoration: preferenceState.useTrueDark
|
|
||||||
? TextDecoration.lineThrough
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onTap: () => showThemeSettingDialog(
|
|
||||||
useTrueDarkMode: preferenceState.useTrueDark,
|
|
||||||
),
|
),
|
||||||
|
onTap: showThemeSettingDialog,
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('About'),
|
title: const Text('About'),
|
||||||
@ -388,7 +383,7 @@ class _ProfileScreenState extends State<ProfileScreen>
|
|||||||
showAboutDialog(
|
showAboutDialog(
|
||||||
context: context,
|
context: context,
|
||||||
applicationName: 'Hacki',
|
applicationName: 'Hacki',
|
||||||
applicationVersion: 'v0.2.5',
|
applicationVersion: 'v0.2.6',
|
||||||
applicationIcon: ClipRRect(
|
applicationIcon: ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(
|
borderRadius: const BorderRadius.all(
|
||||||
Radius.circular(12),
|
Radius.circular(12),
|
||||||
@ -577,13 +572,7 @@ class _ProfileScreenState extends State<ProfileScreen>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showThemeSettingDialog({bool useTrueDarkMode = false}) {
|
void showThemeSettingDialog() {
|
||||||
if (useTrueDarkMode) {
|
|
||||||
showSnackBar(
|
|
||||||
content: "Can't choose theme when using true dark mode.",
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showDialog<void>(
|
showDialog<void>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (_) {
|
builder: (_) {
|
||||||
|
@ -559,6 +559,7 @@ class _StoryScreenState extends State<StoryScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> onFeatureDiscoveryDismissed() {
|
Future<bool> onFeatureDiscoveryDismissed() {
|
||||||
|
HapticFeedback.lightImpact();
|
||||||
ScaffoldMessenger.of(context).clearSnackBars();
|
ScaffoldMessenger.of(context).clearSnackBars();
|
||||||
showSnackBar(content: 'Tap on icon to continue');
|
showSnackBar(content: 'Tap on icon to continue');
|
||||||
return Future<bool>.value(false);
|
return Future<bool>.value(false);
|
||||||
|
@ -181,7 +181,7 @@ class CommentTile extends StatelessWidget {
|
|||||||
else if (state.collapsed)
|
else if (state.collapsed)
|
||||||
const Center(
|
const Center(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: EdgeInsets.symmetric(vertical: 12),
|
padding: EdgeInsets.only(bottom: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
'collapsed',
|
'collapsed',
|
||||||
style:
|
style:
|
||||||
|
@ -1231,7 +1231,7 @@ packages:
|
|||||||
name: workmanager
|
name: workmanager
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.1"
|
version: "0.5.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
name: hacki
|
name: hacki
|
||||||
description: A Hacker News reader.
|
description: A Hacker News reader.
|
||||||
version: 0.2.5+39
|
version: 0.2.6+40
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
@ -56,7 +56,7 @@ dependencies:
|
|||||||
universal_platform: ^1.0.0+1
|
universal_platform: ^1.0.0+1
|
||||||
url_launcher: ^6.0.10
|
url_launcher: ^6.0.10
|
||||||
wakelock: ^0.6.1+2
|
wakelock: ^0.6.1+2
|
||||||
workmanager: ^0.4.1
|
workmanager: ^0.5.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
bloc_test: ^9.0.3
|
bloc_test: ^9.0.3
|
||||||
|
@ -9,6 +9,7 @@ void main() {
|
|||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
const HackiApp(
|
const HackiApp(
|
||||||
savedThemeMode: AdaptiveThemeMode.light,
|
savedThemeMode: AdaptiveThemeMode.light,
|
||||||
|
trueDarkMode: false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user