Add real hashtag processing and storage

codemagic-setup
Hank Grabowski 2023-01-18 12:52:32 -05:00
rodzic 2a3c2296a1
commit fa1609bdc3
10 zmienionych plików z 230 dodań i 18 usunięć

Wyświetl plik

@ -2,7 +2,15 @@
A Flutter application for interfacing with the Friendica social network.
For Linux development be sure that libsecret-1-dev and libjsoncpp-dev are installed on the machine. For running only make sure the non-dev versions are...
For Linux development be sure that libsecret-1-dev and libjsoncpp-dev are installed on the machine. For running only
make sure the non-dev versions are...
## Development Notes
Whenever a model is changed that is stored in ObjectBox it is necessary to execute the command:
```bash
flutter pub run build_runner build
```
Licensed with the Mozilla Public License 2.0 copyleft license.

Wyświetl plik

@ -0,0 +1,11 @@
import '../../models/hashtag.dart';
class IHashtagRepo {
void add(Hashtag tag) {
throw UnimplementedError();
}
List<String> getMatchingHashTags(String text) {
throw UnimplementedError();
}
}

Wyświetl plik

@ -0,0 +1,34 @@
import '../../globals.dart';
import '../../models/hashtag.dart';
import '../../objectbox.g.dart';
import '../interfaces/hashtag_repo_intf.dart';
import 'objectbox_cache.dart';
class ObjectBoxHashtagRepo implements IHashtagRepo {
late final Box<Hashtag> box;
ObjectBoxHashtagRepo() {
box = getIt<ObjectBoxCache>().store.box<Hashtag>();
}
@override
void add(Hashtag tag) {
box.putAsync(tag);
}
@override
List<String> getMatchingHashTags(String text) {
return (box
.query(
text.length <= 2
? Hashtag_.tag.startsWith(text, caseSensitive: false)
: Hashtag_.tag.contains(text, caseSensitive: false),
)
.order(Hashtag_.tag)
.build()
..limit = 100)
.find()
.map((h) => h.tag)
.toList();
}
}

Wyświetl plik

@ -7,9 +7,11 @@ import 'package:result_monad/result_monad.dart';
import 'data/interfaces/connections_repo_intf.dart';
import 'data/interfaces/groups_repo.intf.dart';
import 'data/interfaces/hashtag_repo_intf.dart';
import 'data/memory/memory_groups_repo.dart';
import 'data/objectbox/objectbox_cache.dart';
import 'data/objectbox/objectbox_connections_repo.dart';
import 'data/objectbox/objectbox_hashtag_repo.dart';
import 'globals.dart';
import 'models/TimelineIdentifiers.dart';
import 'routes.dart';
@ -54,6 +56,7 @@ void main() async {
final objectBoxCache = await ObjectBoxCache.create();
getIt.registerSingleton<ObjectBoxCache>(objectBoxCache);
getIt.registerSingleton<IConnectionsRepo>(ObjectBoxConnectionsRepo());
getIt.registerSingleton<IHashtagRepo>(ObjectBoxHashtagRepo());
getIt.registerSingleton<IGroupsRepo>(MemoryGroupsRepo());
getIt.registerLazySingleton<ConnectionsManager>(() => ConnectionsManager());
getIt.registerLazySingleton<HashtagService>(() => HashtagService());

Wyświetl plik

@ -0,0 +1,30 @@
import 'package:objectbox/objectbox.dart';
@Entity()
class Hashtag {
@Id()
int id;
@Unique(onConflict: ConflictStrategy.replace)
String tag;
String url;
@Property(type: PropertyType.date)
DateTime lastUpdateTime;
Hashtag({
this.id = 0,
required this.tag,
required this.url,
DateTime? updateTime,
}) : lastUpdateTime = updateTime ?? DateTime.now();
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Hashtag && runtimeType == other.runtimeType && tag == other.tag;
@override
int get hashCode => tag.hashCode;
}

Wyświetl plik

@ -58,10 +58,41 @@
}
],
"relations": []
},
{
"id": "2:8060242331335522964",
"lastPropertyId": "4:985152873657204249",
"name": "Hashtag",
"properties": [
{
"id": "1:3633001791521338712",
"name": "id",
"type": 6,
"flags": 1
},
{
"id": "2:3468373950035339457",
"name": "tag",
"type": 9,
"flags": 34848,
"indexId": "2:6156017341759176249"
},
{
"id": "3:5102584273729210526",
"name": "url",
"type": 9
},
{
"id": "4:985152873657204249",
"name": "lastUpdateTime",
"type": 10
}
],
"relations": []
}
],
"lastEntityId": "1:1213035855270739890",
"lastIndexId": "1:8342366639839511243",
"lastEntityId": "2:8060242331335522964",
"lastIndexId": "2:6156017341759176249",
"lastRelationId": "0:0",
"lastSequenceId": "0:0",
"modelVersion": 5,

Wyświetl plik

@ -15,6 +15,7 @@ import 'package:objectbox/objectbox.dart';
import 'package:objectbox_flutter_libs/objectbox_flutter_libs.dart';
import 'models/connection.dart';
import 'models/hashtag.dart';
export 'package:objectbox/objectbox.dart'; // so that callers only have to import this file
@ -73,6 +74,36 @@ final _entities = <ModelEntity>[
flags: 0)
],
relations: <ModelRelation>[],
backlinks: <ModelBacklink>[]),
ModelEntity(
id: const IdUid(2, 8060242331335522964),
name: 'Hashtag',
lastPropertyId: const IdUid(4, 985152873657204249),
flags: 0,
properties: <ModelProperty>[
ModelProperty(
id: const IdUid(1, 3633001791521338712),
name: 'id',
type: 6,
flags: 1),
ModelProperty(
id: const IdUid(2, 3468373950035339457),
name: 'tag',
type: 9,
flags: 34848,
indexId: const IdUid(2, 6156017341759176249)),
ModelProperty(
id: const IdUid(3, 5102584273729210526),
name: 'url',
type: 9,
flags: 0),
ModelProperty(
id: const IdUid(4, 985152873657204249),
name: 'lastUpdateTime',
type: 10,
flags: 0)
],
relations: <ModelRelation>[],
backlinks: <ModelBacklink>[])
];
@ -96,8 +127,8 @@ Future<Store> openStore(
ModelDefinition getObjectBoxModel() {
final model = ModelInfo(
entities: _entities,
lastEntityId: const IdUid(1, 1213035855270739890),
lastIndexId: const IdUid(1, 8342366639839511243),
lastEntityId: const IdUid(2, 8060242331335522964),
lastIndexId: const IdUid(2, 6156017341759176249),
lastRelationId: const IdUid(0, 0),
lastSequenceId: const IdUid(0, 0),
retiredEntityUids: const [],
@ -160,6 +191,40 @@ ModelDefinition getObjectBoxModel() {
..dbStatus =
const fb.Int64Reader().vTableGet(buffer, rootOffset, 18, 0);
return object;
}),
Hashtag: EntityDefinition<Hashtag>(
model: _entities[1],
toOneRelations: (Hashtag object) => [],
toManyRelations: (Hashtag object) => {},
getId: (Hashtag object) => object.id,
setId: (Hashtag object, int id) {
object.id = id;
},
objectToFB: (Hashtag object, fb.Builder fbb) {
final tagOffset = fbb.writeString(object.tag);
final urlOffset = fbb.writeString(object.url);
fbb.startTable(5);
fbb.addInt64(0, object.id);
fbb.addOffset(1, tagOffset);
fbb.addOffset(2, urlOffset);
fbb.addInt64(3, object.lastUpdateTime.millisecondsSinceEpoch);
fbb.finish(fbb.endTable());
return object.id;
},
objectFromFB: (Store store, ByteData fbData) {
final buffer = fb.BufferContext(fbData);
final rootOffset = buffer.derefObject(0);
final object = Hashtag(
id: const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0),
tag: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 6, ''),
url: const fb.StringReader(asciiOptimization: true)
.vTableGet(buffer, rootOffset, 8, ''))
..lastUpdateTime = DateTime.fromMillisecondsSinceEpoch(
const fb.Int64Reader().vTableGet(buffer, rootOffset, 10, 0));
return object;
})
};
@ -204,3 +269,19 @@ class Connection_ {
static final lastUpdateTime =
QueryIntegerProperty<Connection>(_entities[0].properties[8]);
}
/// [Hashtag] entity fields to define ObjectBox queries.
class Hashtag_ {
/// see [Hashtag.id]
static final id = QueryIntegerProperty<Hashtag>(_entities[1].properties[0]);
/// see [Hashtag.tag]
static final tag = QueryStringProperty<Hashtag>(_entities[1].properties[1]);
/// see [Hashtag.url]
static final url = QueryStringProperty<Hashtag>(_entities[1].properties[2]);
/// see [Hashtag.lastUpdateTime]
static final lastUpdateTime =
QueryIntegerProperty<Hashtag>(_entities[1].properties[3]);
}

Wyświetl plik

@ -0,0 +1,12 @@
import '../../models/hashtag.dart';
extension HashtagMastodonExtensions on Hashtag {
static Hashtag fromJson(Map<String, dynamic> json) {
final tag = json['name'];
final url = json['url'];
return Hashtag(
tag: tag,
url: url,
);
}
}

Wyświetl plik

@ -10,6 +10,7 @@ import '../../services/connections_manager.dart';
import '../../services/hashtag_service.dart';
import '../../utils/dateutils.dart';
import 'connection_mastodon_extensions.dart';
import 'hashtag_mastodon_extensions.dart';
final _logger = Logger('TimelineEntryMastodonExtensions');
@ -75,9 +76,9 @@ extension TimelineEntryMastodonExtensions on TimelineEntry {
final List<dynamic>? tags = json['tags'];
if (tags?.isNotEmpty ?? false) {
final tagManager = getIt<HashtagService>();
for (final tag in tags!) {
final tagName = tag['name'];
tagManager.addHashtage(tagName);
for (final tagJson in tags!) {
final tag = HashtagMastodonExtensions.fromJson(tagJson);
tagManager.add(tag);
}
}

Wyświetl plik

@ -1,21 +1,22 @@
import 'package:flutter/foundation.dart';
class HashtagService extends ChangeNotifier {
final _hashTags = <String>{};
import '../data/interfaces/hashtag_repo_intf.dart';
import '../globals.dart';
import '../models/hashtag.dart';
void clear() {
_hashTags.clear();
notifyListeners();
class HashtagService extends ChangeNotifier {
late final IHashtagRepo repo;
HashtagService() {
repo = getIt<IHashtagRepo>();
}
void addHashtage(String hashtag) {
_hashTags.add(hashtag);
void add(Hashtag tag) {
repo.add(tag);
notifyListeners();
}
List<String> getMatchingHashTags(String searchString) {
return _hashTags
.where((tag) => tag.toLowerCase().contains(searchString.toLowerCase()))
.toList();
return repo.getMatchingHashTags(searchString);
}
}