Skip to content

Commit

Permalink
Add settings page, import export feature, version bump
Browse files Browse the repository at this point in the history
  • Loading branch information
FuturisticGoo committed Dec 16, 2024
1 parent b536786 commit ff3fb92
Show file tree
Hide file tree
Showing 15 changed files with 389 additions and 187 deletions.
112 changes: 0 additions & 112 deletions assets/emoticons.csv

This file was deleted.

1 change: 0 additions & 1 deletion assets/tag_to_emoticon_map.json

This file was deleted.

2 changes: 1 addition & 1 deletion lib/core/constants.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const emoticonsSourceDbName = "emoticons_source.sqlite";
const emoticonsSourceDbAsset = "assets/$emoticonsSourceDbName";
const version = "0.1.2";
const version = "0.1.3";
const isFirstTimeKey = "isFirstTime";
const emoticonsListKey = "emoticons";
const sqldbName = "emoticons_sqlite";
Expand Down
52 changes: 26 additions & 26 deletions lib/core/settings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ import 'package:sqlite3/sqlite3.dart';
part 'settings.g.dart';

@JsonSerializable()
class Settings extends Equatable {
class GlobalSettings extends Equatable {
final bool isFirstTime;
final String lastUsedVersion;
bool get isUpdated {
return lastUsedVersion != version;
}

const Settings({
const GlobalSettings({
required this.isFirstTime,
required this.lastUsedVersion,
});
Map<String, dynamic> toJson() => _$SettingsToJson(this);
factory Settings.fromJson(Map<String, dynamic> json) =>
_$SettingsFromJson(json);
Map<String, dynamic> toJson() => _$GlobalSettingsToJson(this);
factory GlobalSettings.fromJson(Map<String, dynamic> json) =>
_$GlobalSettingsFromJson(json);
@override
List<Object?> get props => [
isFirstTime,
Expand All @@ -30,8 +30,8 @@ class Settings extends Equatable {
}

abstract class SettingsSource {
Future<Settings> getSavedSettings();
Future<void> saveSettings(Settings newSettings);
Future<GlobalSettings> getSavedSettings();
Future<void> saveSettings(GlobalSettings newSettings);
}

class SettingsSourceDb implements SettingsSource {
Expand All @@ -48,14 +48,14 @@ CREATE TABLE IF NOT EXISTS $sqldbSettingsTableName
}

@override
Future<Settings> getSavedSettings() async {
Future<GlobalSettings> getSavedSettings() async {
await _ensureTable();
final settingsResult = db.select("""
SELECT $sqldbSettingsJson FROM $sqldbSettingsTableName
WHERE $sqldbSettingsId==$sqldbSettingsIdConstant
""");
if (settingsResult.isEmpty) {
return const Settings(
return const GlobalSettings(
isFirstTime: true,
lastUsedVersion: version,
);
Expand All @@ -65,12 +65,12 @@ WHERE $sqldbSettingsId==$sqldbSettingsIdConstant
settingsResult.first[sqldbSettingsJson],
),
);
return Settings.fromJson(settingsJson);
return GlobalSettings.fromJson(settingsJson);
}
}

@override
Future<void> saveSettings(Settings newSettings) async {
Future<void> saveSettings(GlobalSettings newSettings) async {
await _ensureTable();
db.execute("""
DELETE FROM $sqldbSettingsTableName
Expand All @@ -91,38 +91,38 @@ VALUES
}
}

sealed class SettingsState {
const SettingsState();
sealed class GlobalSettingsState {
const GlobalSettingsState();
}

class SettingsInitial implements SettingsState {
const SettingsInitial();
class GlobalSettingsInitial implements GlobalSettingsState {
const GlobalSettingsInitial();
}

class SettingsLoading implements SettingsState {
const SettingsLoading();
class GlobalSettingsLoading implements GlobalSettingsState {
const GlobalSettingsLoading();
}

class SettingsLoaded implements SettingsState {
final Settings settings;
const SettingsLoaded({
class GlobalSettingsLoaded implements GlobalSettingsState {
final GlobalSettings settings;
const GlobalSettingsLoaded({
required this.settings,
});
}

class SettingsCubit extends Cubit<SettingsState> {
class GlobalSettingsCubit extends Cubit<GlobalSettingsState> {
final SettingsSource settingsSource;

SettingsCubit({
GlobalSettingsCubit({
required this.settingsSource,
}) : super(const SettingsInitial()) {
}) : super(const GlobalSettingsInitial()) {
_loadSettings();
}

Future<void> _loadSettings() async {
emit(const SettingsLoading());
emit(const GlobalSettingsLoading());
emit(
SettingsLoaded(
GlobalSettingsLoaded(
settings: await settingsSource.getSavedSettings(),
),
);
Expand All @@ -132,7 +132,7 @@ class SettingsCubit extends Cubit<SettingsState> {
await _loadSettings();
}

Future<void> saveSettings(Settings newSettings) async {
Future<void> saveSettings(GlobalSettings newSettings) async {
await settingsSource.saveSettings(newSettings);
}
}
6 changes: 4 additions & 2 deletions lib/core/settings.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions lib/cubit/settings_cubit.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:emotic/data/emoticons_repository.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
part 'settings_state.dart';

class SettingsCubit extends Cubit<SettingsState> {
final EmoticonsRepository emoticonsRepository;
SettingsCubit({
required this.emoticonsRepository,
}) : super(SettingsInitial()) {
emit(SettingsLoading());
emit(SettingsLoaded());
}

Future<void> clearAllData() async {
emit(SettingsLoading());
await emoticonsRepository.clearAllData();
emit(SettingsLoaded(snackBarMessage: "Cleared data"));
}

Future<void> exportData() async {
emit(SettingsLoading());
final result = await emoticonsRepository.exportToFile();
if (result.isError) {
emit(SettingsLoaded(
snackBarMessage: "Error exporting: ${result.asError!.error}",
));
} else {
emit(SettingsLoaded(
snackBarMessage: "Export successful",
));
}
}

Future<void> importData() async {
emit(SettingsLoading());
final result = await emoticonsRepository.importFromFile();
if (result.isError) {
emit(SettingsLoaded(
snackBarMessage: "Error reading data: ${result.asError!.error}",
));
} else {
emit(SettingsLoaded(
snackBarMessage: "Import successful",
));
}
}
}
18 changes: 18 additions & 0 deletions lib/cubit/settings_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
part of 'settings_cubit.dart';

sealed class SettingsState {}

class SettingsInitial extends SettingsState {}

class SettingsLoading extends SettingsState {}

class SettingsLoaded extends SettingsState with EquatableMixin {
final String? snackBarMessage;
SettingsLoaded({
this.snackBarMessage,
});
@override
List<Object?> get props => [
snackBarMessage,
];
}
25 changes: 25 additions & 0 deletions lib/data/emoticons_repository.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:async/async.dart';
import 'package:emotic/core/emoticon.dart';
import 'package:emotic/data/emoticons_source.dart';

Expand Down Expand Up @@ -50,4 +51,28 @@ class EmoticonsRepository {
Future<void> deleteTag({required String tag}) async {
return database.deleteTag(tag: tag);
}

Future<void> clearAllData() async {
return database.clearAllData();
}

Future<Result<void>> exportToFile() async {
if (database is EmoticonsSqliteSource) {
return (database as EmoticonsSqliteSource).exportToDb();
} else {
return Result.error(
UnimplementedError("Export unavailable for this source"));
}
}

Future<Result<void>> importFromFile() async {
if (database is EmoticonsSqliteSource) {
return (database as EmoticonsSqliteSource).importFromDb(
importStrategy: ImportStrategy.merge,
);
} else {
return Result.error(
UnimplementedError("Import unavailable for this source"));
}
}
}
Loading

0 comments on commit ff3fb92

Please sign in to comment.