Skip to content

Commit

Permalink
update.
Browse files Browse the repository at this point in the history
  • Loading branch information
Livinglist committed Jul 19, 2024
1 parent d1957ff commit 6c78700
Show file tree
Hide file tree
Showing 16 changed files with 96 additions and 35 deletions.
7 changes: 7 additions & 0 deletions assets/remote-config-dev.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"athingComtrSelector": "#hnmain > tbody > tr > td > table > tbody > .athing.comtr",
"commentTextSelector": "td > table > tbody > tr > td.default > div.comment > div.commtext",
"commentHeadSelector": "td > table > tbody > tr > td.default > div > span > a",
"commentAgeSelector": "td > table > tbody > tr > td.default > div > span > span.age",
"commentIndentSelector": "td > table > tbody > tr > td.ind"
}
19 changes: 11 additions & 8 deletions lib/blocs/stories/stories_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
static const int _largePageSize = 20;
static const int _tabletSmallPageSize = 15;
static const int _tabletLargePageSize = 25;
static const String _logPrefix = '[StoriesBloc]';

Future<void> onInitialize(
StoriesInitialize event,
Expand Down Expand Up @@ -245,7 +246,9 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {

final Story story = event.story;
if (state.storiesByType[event.type]?.contains(story) ?? false) {
_logger.d('story already exists.');
_logger.d(
'$_logPrefix story ${story.id} for ${event.type} already exists.',
);
return;
}
final bool hasRead = await _preferenceRepository.hasRead(story.id);
Expand Down Expand Up @@ -349,20 +352,20 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
<StreamSubscription<Comment>>[];
for (final int id in ids) {
if (state.downloadStatus == StoriesDownloadStatus.canceled) {
_logger.d('aborting downloading');
_logger.d('$_logPrefix aborting downloading');

for (final StreamSubscription<Comment> stream in downloadStreams) {
await stream.cancel();
}

_logger.d('deleting downloaded contents');
_logger.d('$_logPrefix deleting downloaded contents');
await _offlineRepository.deleteAllStoryIds();
await _offlineRepository.deleteAllStories();
await _offlineRepository.deleteAllComments();
break;
}

_logger.d('fetching story $id');
_logger.d('$_logPrefix fetching story $id');
final Story? story = await _hackerNewsRepository.fetchStory(id: id);

if (story == null) {
Expand All @@ -382,7 +385,7 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
await _offlineRepository.cacheStory(story: story);

if (story.url.isNotEmpty && includingWebPage) {
_logger.i('downloading ${story.url}');
_logger.i('$_logPrefix downloading ${story.url}');
await _offlineRepository.cacheUrl(url: story.url);
}

Expand All @@ -399,19 +402,19 @@ class StoriesBloc extends Bloc<StoriesEvent, StoriesState> {
.listen(
(Comment comment) {
if (state.downloadStatus == StoriesDownloadStatus.canceled) {
_logger.d('aborting downloading from comments stream');
_logger.d('$_logPrefix aborting downloading from comments stream');
downloadStream?.cancel();
return;
}

_logger.d('fetched comment ${comment.id}');
_logger.d('$_logPrefix fetched comment ${comment.id}');
unawaited(
_offlineRepository.cacheComment(comment: comment),
);
},
)..onDone(() {
_logger.d(
'''finished downloading story ${story.id} with ${story.descendants} comments''',
'''$_logPrefix finished downloading story ${story.id} with ${story.descendants} comments''',
);
add(StoryDownloaded(skipped: false));
});
Expand Down
18 changes: 12 additions & 6 deletions lib/cubits/comments/comments_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class CommentsCubit extends Cubit<CommentsState> {
<int, StreamSubscription<Comment>>{};

static const int _webFetchingCmtCountLowerLimit = 5;
static const String _logPrefix = '[CommentsCubit]';

Future<bool> get _shouldFetchFromWeb async {
final bool isOnWifi = await _isOnWifi;
Expand Down Expand Up @@ -182,13 +183,14 @@ class CommentsCubit extends Cubit<CommentsState> {
case CommentsOrder.natural:
final bool shouldFetchFromWeb = await _shouldFetchFromWeb;
if (fetchFromWeb && shouldFetchFromWeb) {
_logger.d('fetching from web.');
_logger
.d('$_logPrefix fetching comments of ${item.id} from web.');
commentStream = _hackerNewsWebRepository
.fetchCommentsStream(state.item)
.handleError((dynamic e) {
_streamSubscription?.cancel();

_logger.e(e);
_logger.e('$_logPrefix $e');

switch (e.runtimeType) {
case RateLimitedException:
Expand All @@ -205,7 +207,8 @@ class CommentsCubit extends Cubit<CommentsState> {
}
});
} else {
_logger.d('fetching from API.');
_logger
.d('$_logPrefix fetching comments of ${item.id} from API.');
commentStream =
_hackerNewsRepository.fetchAllCommentsRecursivelyStream(
ids: kids,
Expand Down Expand Up @@ -280,11 +283,13 @@ class CommentsCubit extends Cubit<CommentsState> {
case CommentsOrder.natural:
final bool shouldFetchFromWeb = await _shouldFetchFromWeb;
if (fetchFromWeb && shouldFetchFromWeb) {
_logger.d('fetching from web.');
_logger.d(
'$_logPrefix fetching comments of ${item.id} from web.',
);
commentStream = _hackerNewsWebRepository
.fetchCommentsStream(state.item)
.handleError((dynamic e) {
_logger.e(e);
_logger.e('$_logPrefix $e');

switch (e.runtimeType) {
case RateLimitedException:
Expand All @@ -301,7 +306,8 @@ class CommentsCubit extends Cubit<CommentsState> {
}
});
} else {
_logger.d('fetching from API.');
_logger
.d('$_logPrefix fetching comments of ${item.id} from API.');
commentStream = _hackerNewsRepository
.fetchAllCommentsRecursivelyStream(ids: kids);
}
Expand Down
3 changes: 2 additions & 1 deletion lib/cubits/notification/notification_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class NotificationCubit extends Cubit<NotificationState> {
static const Duration _refreshInterval = Duration(minutes: 5);
static const int _subscriptionUpperLimit = 15;
static const int _pageSize = 20;
static const String _logPrefix = '[NotificationCubit]';

Future<void> init() async {
emit(NotificationState.init());
Expand All @@ -78,7 +79,7 @@ class NotificationCubit extends Cubit<NotificationState> {
});

await _preferenceRepository.unreadCommentsIds.then((List<int> unreadIds) {
_logger.i('NotificationCubit: ${unreadIds.length} unread items.');
_logger.i('$_logPrefix ${unreadIds.length} unread items.');
emit(state.copyWith(unreadCommentsIds: unreadIds));
});

Expand Down
3 changes: 2 additions & 1 deletion lib/cubits/preference/preference_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class PreferenceCubit extends Cubit<PreferenceState> {

final PreferenceRepository _preferenceRepository;
final Logger _logger;
static const String _logPrefix = '[PreferenceCubit]';

void init() {
for (final BooleanPreference p
Expand Down Expand Up @@ -73,7 +74,7 @@ class PreferenceCubit extends Cubit<PreferenceState> {
}

void update<T>(Preference<T> preference) {
_logger.i('updating $preference to ${preference.val}');
_logger.i('$_logPrefix updating $preference to ${preference.val}');

emit(state.copyWithPreference(preference));

Expand Down
13 changes: 11 additions & 2 deletions lib/cubits/remote_config/remote_config_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,34 @@ import 'package:flutter/cupertino.dart';
import 'package:hacki/config/locator.dart';
import 'package:hacki/repositories/remote_config_repository.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:logger/logger.dart';

part 'remote_config_state.dart';

class RemoteConfigCubit extends HydratedCubit<RemoteConfigState> {
RemoteConfigCubit({RemoteConfigRepository? remoteConfigRepository})
: _remoteConfigRepository =
RemoteConfigCubit({
RemoteConfigRepository? remoteConfigRepository,
Logger? logger,
}) : _remoteConfigRepository =
remoteConfigRepository ?? locator.get<RemoteConfigRepository>(),
_logger = logger ?? locator.get<Logger>(),
super(RemoteConfigState.init()) {
init();
}

final RemoteConfigRepository _remoteConfigRepository;
final Logger _logger;
static const String _logPrefix = '';

void init() {
_remoteConfigRepository
.fetchRemoteConfig()
.then((Map<String, dynamic> data) {
if (data.isNotEmpty) {
_logger.i('$_logPrefix remote config fetched: $data');
emit(state.copyWith(data: data));
} else {
_logger.i('$_logPrefix empty remote config.');
}
});
}
Expand Down
3 changes: 2 additions & 1 deletion lib/cubits/split_view/split_view_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ class SplitViewCubit extends Cubit<SplitViewState> {

final Logger _logger;
final CommentCache _commentCache;
static const String _logPrefix = '[SplitViewCubit]';

void updateItemScreenArgs(ItemScreenArgs args) {
_logger.i('resetting comments in CommentCache');
_logger.i('$_logPrefix resetting comments in CommentCache');
_commentCache.resetComments();
emit(state.copyWith(itemScreenArgs: args));
}
Expand Down
7 changes: 5 additions & 2 deletions lib/cubits/tab/tab_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,20 @@ class TabCubit extends Cubit<TabState> {

final PreferenceCubit _preferenceCubit;
final Logger _logger;
static const String _logPrefix = '[TabCubit]';

void init() {
final List<StoryType> tabs = _preferenceCubit.state.tabs;

_logger.i('updating tabs to $tabs');
_logger.i('$_logPrefix updating tabs to $tabs');

emit(state.copyWith(tabs: tabs));
}

void update(int startIndex, int endIndex) {
_logger.d('updating ${state.tabs} by moving $startIndex to $endIndex');
_logger.d(
'$_logPrefix updating ${state.tabs} by moving $startIndex to $endIndex',
);
final StoryType tab = state.tabs.elementAt(startIndex);
final List<StoryType> updatedTabs = List<StoryType>.from(state.tabs)
..insert(endIndex, tab)
Expand Down
7 changes: 6 additions & 1 deletion lib/repositories/remote_config_repository.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

class RemoteConfigRepository {
RemoteConfigRepository({Dio? dio}) : _dio = dio ?? Dio();

final Dio _dio;
static const String _path =
'https://raw.githubusercontent.com/Livinglist/Hacki/master/assets/';

Future<Map<String, dynamic>> fetchRemoteConfig() async {
const String fileName =
kReleaseMode ? 'remote-config.json' : 'remote-config-dev.json';
final Response<dynamic> response = await _dio.get(
'https://raw.githubusercontent.com/Livinglist/Hacki/master/assets/remote-config.json',
'$_path$fileName',
);
final String data = response.data as String? ?? '';
final Map<String, dynamic> json = jsonDecode(data) as Map<String, dynamic>;
Expand Down
14 changes: 13 additions & 1 deletion lib/repositories/sembast_repository.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'dart:async';
import 'dart:io';

import 'package:hacki/config/locator.dart';
import 'package:hacki/models/models.dart';
import 'package:hacki/services/services.dart';
import 'package:logger/logger.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:sembast/sembast.dart';
Expand All @@ -17,7 +19,8 @@ class SembastRepository {
SembastRepository({
Database? database,
Database? cache,
}) {
Logger? logger,
}) : _logger = logger ?? locator.get<Logger>() {
if (database == null) {
initializeDatabase();
} else {
Expand All @@ -31,6 +34,9 @@ class SembastRepository {
}
}

final Logger _logger;
static const String _logPrefix = '[SembastRepository]';

Database? _database;
Database? _cache;
List<int>? _idsOfCommentsRepliedToMe;
Expand All @@ -44,6 +50,9 @@ class SembastRepository {
final Directory dir = await getApplicationCacheDirectory();
await dir.create(recursive: true);
final String dbPath = join(dir.path, 'hacki.db');
final File file = File(dbPath);
final FileStat stat = file.statSync();
_logger.i('$_logPrefix hacki.db file size: ${stat.size / 1000000}MB');
final DatabaseFactory dbFactory = databaseFactoryIo;
final Database db = await dbFactory.openDatabase(dbPath);
_database = db;
Expand All @@ -54,6 +63,9 @@ class SembastRepository {
final Directory tempDir = await getTemporaryDirectory();
await tempDir.create(recursive: true);
final String dbPath = join(tempDir.path, 'hacki_cache.db');
final File file = File(dbPath);
final FileStat stat = file.statSync();
_logger.i('$_logPrefix hacki_cache.db file size: ${stat.size / 1000000}MB');
final DatabaseFactory dbFactory = databaseFactoryIo;
final Database db = await dbFactory.openDatabase(dbPath);
_cache = db;
Expand Down
3 changes: 2 additions & 1 deletion lib/screens/home/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ class _HomeScreenState extends State<HomeScreen>
late final StreamSubscription<String?> siriSuggestionStreamSubscription;

static final int tabLength = StoryType.values.length + 1;
static const String logPrefix = '[HomeScreen]';

@override
void didPopNext() {
super.didPopNext();
if (context.read<StoriesBloc>().deviceScreenType ==
DeviceScreenType.mobile) {
locator.get<Logger>().i('resetting comments in CommentCache');
locator.get<Logger>().i('$logPrefix resetting comments in CommentCache');
Future<void>.delayed(
AppDurations.ms500,
locator.get<CommentCache>().resetComments,
Expand Down
9 changes: 9 additions & 0 deletions lib/screens/profile/widgets/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,15 @@ class _SettingsState extends State<Settings> with ItemActionMixin {
),
onTap: showClearCacheDialog,
),
if(preferenceState.isDevModeEnabled)
ListTile(
title: const Text(
'Logs',
),
onTap: (){

},
),
ListTile(
title: const Text('About'),
subtitle: const Text('nothing interesting here.'),
Expand Down
8 changes: 4 additions & 4 deletions lib/services/fetcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ abstract class Fetcher {
final Logger logger = Logger();
final PreferenceRepository preferenceRepository =
PreferenceRepository(logger: logger);

final AuthRepository authRepository = AuthRepository(
preferenceRepository: preferenceRepository,
logger: logger,
);

final HackerNewsRepository hackerNewsRepository = HackerNewsRepository();
final SembastRepository sembastRepository = SembastRepository();

final HackerNewsRepository hackerNewsRepository = HackerNewsRepository(
sembastRepository: sembastRepository,
logger: logger,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();

Expand Down
Loading

0 comments on commit 6c78700

Please sign in to comment.