-
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 provider - 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
- Loading branch information
Showing
38 changed files
with
1,036 additions
and
138 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
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,133 @@ | ||
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<NoteModel> read(int id) async { | ||
// final db = await instance.database; | ||
// final maps = await db.query( | ||
// CampaignActionFields.tableName, | ||
// columns: CampaignActionFields.values, | ||
// where: '${CampaignActionFields.id} = ?', | ||
// whereArgs: [id], | ||
// ); | ||
|
||
// if (maps.isNotEmpty) { | ||
// return NoteModel.fromJson(maps.first); | ||
// } else { | ||
// throw Exception('ID $id not found'); | ||
// } | ||
// } | ||
|
||
Future<List<CampaignAction>> readAll() async { | ||
final db = await instance.database; | ||
const orderBy = '${CampaignActionFields.poiTempId} DESC'; | ||
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} DESC'; | ||
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} DESC'; | ||
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<int> update(NoteModel note) async { | ||
// final db = await instance.database; | ||
// return db.update( | ||
// CampaignActionFields.tableName, | ||
// note.toJson(), | ||
// where: '${CampaignActionFields.id} = ?', | ||
// whereArgs: [note.id], | ||
// ); | ||
// } | ||
|
||
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,25 @@ | ||
part of '../converters.dart'; | ||
|
||
extension CampaignActionParsing on CampaignAction { | ||
PosterCreateModel getSerializedAsPosterCreate() { | ||
var data = jsonDecode(serialized!) as Map<String, dynamic>; | ||
if (data['photo'] != null) { | ||
data['photo'] = (data['photo'] as List<dynamic>).cast<int>(); | ||
} | ||
data['location'] = (data['location'] as List<dynamic>).cast<double>(); | ||
|
||
var model = PosterCreateModel.fromJson(data); | ||
return model; | ||
} | ||
|
||
PosterUpdateModel getSerializedAsPosterUpdate() { | ||
var data = jsonDecode(serialized!) as Map<String, dynamic>; | ||
if (data['newPhoto'] != null) { | ||
data['newPhoto'] = (data['newPhoto'] as List<dynamic>).cast<int>(); | ||
} | ||
data['location'] = (data['location'] as List<dynamic>).cast<double>(); | ||
|
||
var model = PosterUpdateModel.fromJson(data); | ||
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); | ||
} | ||
} |
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, | ||
); | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
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,33 @@ | ||
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) { | ||
return PosterDetailModel( | ||
id: temporaryId.toString(), | ||
status: status, | ||
address: address, | ||
thumbnailUrl: null, | ||
imageUrl: null, | ||
location: location, | ||
comment: comment, | ||
createdAt: '${DateTime.now().getAsLocalDateTimeString()}*', // should mark this as preliminary | ||
isCached: true, | ||
); | ||
} | ||
|
||
PosterUpdateModel mergeWith(PosterUpdateModel newPosterUpdate) { | ||
var oldPosterUdpate = this; | ||
|
||
return newPosterUpdate.copyWith( | ||
removePreviousPhotos: newPosterUpdate.removePreviousPhotos || oldPosterUdpate.removePreviousPhotos, | ||
); | ||
} | ||
} |
Oops, something went wrong.