-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- use sqflite as cache database - store all item actions in cache - use virtual markers to distinct between saved and intermediate state - images are stored on device data instead of stream to reduce mem_usage - auto-discover when add + delete are done in cache (removes item from cache and never stores it)
- Loading branch information
Showing
44 changed files
with
1,177 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,5 +4,6 @@ | |
"gruene", | ||
"housenumber" | ||
], | ||
"files.eol": "\n" | ||
"files.eol": "\n", | ||
"cSpell.enabled": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import 'dart:io'; | ||
|
||
import 'package:gruene_app/features/campaigns/helper/campaign_action.dart'; | ||
import 'package:path/path.dart'; | ||
import 'package:sqflite/sqflite.dart'; | ||
|
||
class CampaignActionDatabase { | ||
static final CampaignActionDatabase instance = CampaignActionDatabase._internal(); | ||
|
||
static Database? _database; | ||
|
||
CampaignActionDatabase._internal(); | ||
|
||
Future<Database> get database async { | ||
return _database ??= await _initDatabase(); | ||
} | ||
|
||
Future<Database> _initDatabase() async { | ||
final databasePath = await getDatabasesPath(); | ||
final path = join(databasePath, 'campaign_action_db.db'); | ||
await File(path).delete(); | ||
return await openDatabase( | ||
path, | ||
version: 1, | ||
onCreate: _createDatabase, | ||
); | ||
} | ||
|
||
Future<void> _createDatabase(Database db, _) async { | ||
return await db.execute(''' | ||
CREATE TABLE ${CampaignActionFields.tableName} ( | ||
${CampaignActionFields.id} ${CampaignActionFields.idType}, | ||
${CampaignActionFields.poiId} ${CampaignActionFields.intTypeNullable}, | ||
${CampaignActionFields.poiTempId} ${CampaignActionFields.intType}, | ||
${CampaignActionFields.actionType} ${CampaignActionFields.intType}, | ||
${CampaignActionFields.serialized} ${CampaignActionFields.textTypeNullable} | ||
) | ||
'''); | ||
} | ||
|
||
Future<CampaignAction> create(CampaignAction campaignAction) async { | ||
final db = await instance.database; | ||
final id = await db.insert(CampaignActionFields.tableName, campaignAction.toMap()); | ||
return campaignAction.copyWith(id: id); | ||
} | ||
|
||
Future<List<CampaignAction>> readAll() async { | ||
final db = await instance.database; | ||
const orderBy = '${CampaignActionFields.poiTempId} ASC, ${CampaignActionFields.id} ASC'; | ||
final result = await db.query(CampaignActionFields.tableName, orderBy: orderBy); | ||
return result.map((json) => CampaignAction.fromMap(json)).toList(); | ||
} | ||
|
||
Future<List<CampaignAction>> readAllByActionType(List<int> posterActions) async { | ||
final db = await instance.database; | ||
const orderBy = '${CampaignActionFields.poiTempId} ASC, ${CampaignActionFields.id} ASC'; | ||
final result = await db.query( | ||
CampaignActionFields.tableName, | ||
orderBy: orderBy, | ||
where: '${CampaignActionFields.actionType} IN (${List.filled(posterActions.length, '?').join(',')})', | ||
whereArgs: posterActions, | ||
); | ||
return result.map((json) => CampaignAction.fromMap(json)).toList(); | ||
} | ||
|
||
Future<List<CampaignAction>> getActionsWithPoiId(String poiId) async { | ||
final db = await instance.database; | ||
const orderBy = '${CampaignActionFields.poiTempId} ASC, ${CampaignActionFields.id} ASC'; | ||
final result = await db.query( | ||
CampaignActionFields.tableName, | ||
orderBy: orderBy, | ||
where: '${CampaignActionFields.poiId} = ? OR ${CampaignActionFields.poiTempId} = ?', | ||
whereArgs: [poiId, poiId], | ||
); | ||
return result.map((json) => CampaignAction.fromMap(json)).toList(); | ||
} | ||
|
||
Future<void> update(CampaignAction campaignAction) async { | ||
final db = await instance.database; | ||
db.update( | ||
CampaignActionFields.tableName, | ||
campaignAction.toMap(), | ||
where: '${CampaignActionFields.id} = ?', | ||
whereArgs: [campaignAction.id], | ||
); | ||
} | ||
|
||
Future<void> updatePoiId(int oldId, int newId) async { | ||
final db = await instance.database; | ||
await db.update( | ||
CampaignActionFields.tableName, | ||
{CampaignActionFields.poiId: newId}, | ||
where: '${CampaignActionFields.poiId} = ?', | ||
whereArgs: [oldId], | ||
); | ||
} | ||
|
||
Future<int> delete(int id) async { | ||
final db = await instance.database; | ||
return await db.delete( | ||
CampaignActionFields.tableName, | ||
where: '${CampaignActionFields.id} = ?', | ||
whereArgs: [id], | ||
); | ||
} | ||
|
||
Future<void> close() async { | ||
final db = await instance.database; | ||
db.close(); | ||
} | ||
|
||
Future<int> getCount() async { | ||
final db = await instance.database; | ||
int count = Sqflite.firstIntValue(await db.rawQuery('SELECT COUNT(*) FROM ${CampaignActionFields.tableName}')) ?? 0; | ||
return count; | ||
} | ||
} | ||
|
||
class CampaignActionFields { | ||
static const String tableName = 'campaign_action'; | ||
static const String idType = 'INTEGER PRIMARY KEY AUTOINCREMENT'; | ||
static const String textTypeNullable = 'TEXT'; | ||
static const String intType = 'INTEGER NOT NULL'; | ||
static const String intTypeNullable = 'INTEGER'; | ||
static const String id = '_id'; | ||
static const String poiId = 'poiId'; | ||
static const String poiTempId = 'poiTempId'; | ||
static const String actionType = 'actionType'; | ||
static const String serialized = 'serialized'; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
part of '../converters.dart'; | ||
|
||
extension CampaignActionParsing on CampaignAction { | ||
PosterCreateModel getAsPosterCreate() { | ||
var data = jsonDecode(serialized!) as Map<String, dynamic>; | ||
var model = PosterCreateModel.fromJson(data.convertLatLongField()); | ||
return model; | ||
} | ||
|
||
PosterUpdateModel getAsPosterUpdate() { | ||
var data = jsonDecode(serialized!) as Map<String, dynamic>; | ||
var model = PosterUpdateModel.fromJson(data.updateIdField(poiId!).convertLatLongField()); | ||
|
||
return model; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
part of '../converters.dart'; | ||
|
||
extension DateTimeParsing on DateTime { | ||
String getAsLocalDateTimeString() { | ||
DateTime utcDateTime = this; | ||
DateTime localDateTime = utcDateTime.toLocal(); | ||
final dateString = DateFormat(t.campaigns.poster.date_format).format(localDateTime); | ||
final timeString = DateFormat(t.campaigns.poster.time_format).format(localDateTime); | ||
return t.campaigns.poster.datetime_display_template | ||
.replaceAll('{date}', dateString) | ||
.replaceAll('{time}', timeString); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
lib/app/services/converters/map_string_dynamic_converter.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
part of '../converters.dart'; | ||
|
||
extension MapStringDynamicConverter on Map<String, dynamic> { | ||
Map<String, dynamic> convertLatLongField({String fieldName = 'location'}) { | ||
this[fieldName] = (this[fieldName] as List<dynamic>).cast<double>(); | ||
return this; | ||
} | ||
|
||
Map<String, dynamic> updateIdField(int id) { | ||
this['id'] = id.toString(); | ||
return this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
lib/app/services/converters/poster_create_model_parsing.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
part of '../converters.dart'; | ||
|
||
extension PosterCreateModelParsing on PosterCreateModel { | ||
MarkerItemModel transformToVirtualMarkerItem(int temporaryId) { | ||
return MarkerItemModel.virtual( | ||
id: temporaryId, | ||
status: PoiServiceType.poster.getAsMarkerItemStatus(PosterStatus.ok), | ||
location: location, | ||
); | ||
} | ||
|
||
PosterDetailModel transformToPosterDetailModel(int temporaryId) { | ||
return PosterDetailModel( | ||
id: temporaryId.toString(), | ||
status: PosterStatus.ok, | ||
address: address, | ||
thumbnailUrl: imageFileLocation, | ||
imageUrl: imageFileLocation, | ||
location: location, | ||
comment: '', | ||
createdAt: '${DateTime.now().getAsLocalDateTimeString()}*', // should mark this as preliminary | ||
isCached: true, | ||
); | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
lib/app/services/converters/poster_update_model_parsing.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
part of '../converters.dart'; | ||
|
||
extension PosterUpdateModelParsing on PosterUpdateModel { | ||
MarkerItemModel transformToVirtualMarkerItem() { | ||
return MarkerItemModel.virtual( | ||
id: int.parse(id), | ||
status: PoiServiceType.poster.getAsMarkerItemStatus(status), | ||
location: location, | ||
); | ||
} | ||
|
||
PosterDetailModel transformToPosterDetailModel(int temporaryId) { | ||
var newPosterDetail = oldPosterDetail.copyWith( | ||
status: status, | ||
address: address, | ||
thumbnailUrl: newImageFileLocation ?? (!removePreviousPhotos ? oldPosterDetail.thumbnailUrl : null), | ||
imageUrl: newImageFileLocation ?? (!removePreviousPhotos ? oldPosterDetail.imageUrl : null), | ||
comment: comment, | ||
isCached: true, | ||
); | ||
return newPosterDetail; | ||
} | ||
|
||
PosterUpdateModel mergeWith(PosterUpdateModel newPosterUpdate) { | ||
var oldPosterUdpate = this; | ||
|
||
return newPosterUpdate.copyWith( | ||
removePreviousPhotos: newPosterUpdate.removePreviousPhotos || oldPosterUdpate.removePreviousPhotos, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
part of '../converters.dart'; | ||
|
||
extension StringExtension on String { | ||
bool isNetworkImageUrl() => Uri.parse(this).hasScheme; | ||
} |
Oops, something went wrong.