diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6dc313a..04dc7a7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@
* Clicking on "Comments" stats loads the post comment view
* Moved the utility buttons from the bottom of the post/comment to a popup menu on the upper right
* Show visibility of images in the gallery
+ * Notifications now show truncated post bodies not the full body
* Sort the notifications by unread by category and then unread chronological so:
* Unread Direct Messages (sorted newest first)
* Unresolved Follow/Connection Requests (sorted newest first)
@@ -21,6 +22,7 @@
* Eliminated excessive cropping of top of Contacts Screen
* Can go to account profiles of accounts never seen before from the Interactions Screen (list of which accounts,
liked, reshared, etc)
+ * Notifications refreshing more stable
* New Features
* Post/Comment Editing
* Being able to set the posts as private and a single group it is visible to (or "Followers", the default)
diff --git a/README.md b/README.md
index 8d10009..0525711 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
A Flutter application for interfacing with the Friendica social network.
-
+
-
+
## Project Objectives
diff --git a/beta-program.md b/beta-program.md
index f3d7a89..93f42f4 100644
--- a/beta-program.md
+++ b/beta-program.md
@@ -57,15 +57,18 @@ wanted to lay out some expectations before getting into the small details
* Logging in with username/password and OAuth. These are stored using the OS specific key vaults
* Having multiple accounts logged in at the same time and switching between them
-* Writing **public** posts
+* Writing public and private posts
+ * For private posts have to select one of the Groups you have users setup for or all followers.
* Typing @ brings up a list of all known fediverse accounts that the app has ever seen as you
type (but not all that your server has seen)
* Typing # brings up a list of all known hashtags that the app has ever seen as you type (but
not all that your server has seen)
- * Very basic markdown (wrapping in stars for bold/italics)
+ * Very basic markdown (wrapping in stars for bold/italics, bulletted list)
+ * Explicit link preview builder
* Adding new images to posts
* Image posting with easy means of adding ALT text
* Attaching existing images to posts
+* Editing posts and comments
* Resharing posts
* Direct (private) messaging
* Browsing timelines including from groups you've created. In this app "Home" is the same as the "
@@ -87,25 +90,21 @@ wanted to lay out some expectations before getting into the small details
change in the near future)
* Show list of who liked and reshared posts/comments
* Detailed information about users, such as description fields
+* Notifications browsing and dismissing
+* Search through server using freeform text or "%" wild card for: accounts, statuses, hashtags
+* Direct Load links to Fediverse posts and accounts within the app
### Big things I want to have working in the near future:
* More timeline types like Comments, "By Activity", etc.
* Better timeline UX to allow for "in-fill"
-* Fine grain details about users (last post, last update)
* Better data display on larger format displays by doing things like:
* Allowing images/thumbnails to be larger
* Limiting maximum width of timeline columns
* Nicer aesthetics
* Fix below identified issues
-* Notifications broken into:
- * Messages (from message system)
- * Friend requests
- * Real notifications
-* More greedy loading of notifications when not in low bandwidth mode
* More intuitive timeline controls
* Real paging across the board
- * Notifications
* Comments
* Offline caching of older content
* Dynamic search of locally known posts and hashtags.
@@ -115,14 +114,9 @@ wanted to lay out some expectations before getting into the small details
### Further out things I want to have working:
-* Private posts
-* Post editing
* Profile editor
* Opening accounts, tags, etc within posts within the app itself through user's home server
-* Equivalent of account/post link paste and processing from website version
* Group creation, deletion, renaming
-* Being able to load accounts and/or posts from links from other users within app
-* Open fediverse accounts/files within app
* Nitter replacement of Twitter links
* User configurable Server blocking
* Server-side searching tied into profiles, posts, hashtags
@@ -136,7 +130,6 @@ wanted to lay out some expectations before getting into the small details
* Creating new forums through the application
* Site administration
* Adding videos or files to posts
-* Multi-account logins
## General behaviors/problems to be aware of:
@@ -147,7 +140,7 @@ wanted to lay out some expectations before getting into the small details
* Content Warnings/Spoiler Text on *posts* aren't federating over to Mastodon well so only use it on
Comments for now (fixed on servers running Friendica 2023.03)
* ALT text on images should not have any quotation marks as it breaks when federating over to
- Diaspora for the time being
+ Diaspora for the time being (fixed on servers running Friendica 2023.03)
* Portrait videos overflow their boxes in the timeline
* Blocked/ignored user's content is still returned by the API (Fixed in Friendica 2023.03)
* Paging for some of the endpoints either isn't wired in yet or is not working as needed server
@@ -156,14 +149,10 @@ wanted to lay out some expectations before getting into the small details
* Gallery Contents
* Comments on posts
* Tags
- * Notifications
* Blocked user list
### Cumbersome and hopefully improved in the very near future:
-* The only post type that is supported right now are public posts therefore all posts you write
- through the app will have this privacy level.
-* Notifications need to be manually refreshed.
* Sometimes timelines get confused so swapping between the different groups/timelines creates a
muddled display. Restarting the app fixes this.
* Some images within posts, usually graphical emojis, are rendered drastically larger than they
diff --git a/install.md b/install.md
index 3f224cd..c18da14 100644
--- a/install.md
+++ b/install.md
@@ -6,11 +6,11 @@ For more information about the current beta testing program
# Latest Binaries:
-* [Android v0.2.0](https://mysocialportal-relatica.nyc3.cdn.digitaloceanspaces.com/v0.2.0%2Frelatica_v0.2.0.apk.zip)
-* iPhone/iPad v0.2.0: This is only available through TestFlight. Please contact me for access.
-* [Windows (Intel) v0.2.0](https://mysocialportal-relatica.nyc3.cdn.digitaloceanspaces.com/v0.2.0%2FRelatica_v0.2.0_x64_win.zip)
-* macOS v0.2.0 This is only available through TestFlight. Please contact me for access.
-* [Linux (Intel Ubuntu 22) v0.2.0](https://mysocialportal-relatica.nyc3.cdn.digitaloceanspaces.com/v0.2.0%2Frelatica_v0.2.0_linux_x64_ubuntu22.zip)
+* [Android v0.3.0](https://mysocialportal-relatica.nyc3.cdn.digitaloceanspaces.com/v0.3.0%2Frelatica_v0.3.0.apk.zip)
+* iPhone/iPad v0.3.0: This is only available through TestFlight. Please contact me for access.
+* [Windows (Intel) v0.3.0](https://mysocialportal-relatica.nyc3.cdn.digitaloceanspaces.com/v0.3.0%2FRelatica_v0.3.0_win_x64.zip)
+* macOS v0.3.0 This is only available through TestFlight. Please contact me for access.
+* [Linux (Intel Ubuntu 22) v0.3.0](https://mysocialportal-relatica.nyc3.cdn.digitaloceanspaces.com/v0.3.0%2Frelatica_v0.3.0_linux_x64_ubuntu22.zip)
## Mobile
diff --git a/lib/data/objectbox/objectbox_cache.dart b/lib/data/objectbox/objectbox_cache.dart
index c24c3b4..c847d6b 100644
--- a/lib/data/objectbox/objectbox_cache.dart
+++ b/lib/data/objectbox/objectbox_cache.dart
@@ -4,27 +4,45 @@ import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart';
+import '../../globals.dart';
import '../../objectbox.g.dart';
class ObjectBoxCache {
static final _logger = Logger('ObjectBoxCache');
+ static final _openCaches = {};
late final Store store;
ObjectBoxCache._create(this.store);
- static Future create(
- {String baseDir = 'objectboxcache', String? subDir}) async {
+ static Future create({
+ String baseDir = 'objectboxcache',
+ String? subDir,
+ }) async {
final docsDir = await getApplicationSupportDirectory();
final path = p.join(docsDir.path, baseDir, subDir);
+ _logger.info('ObjectBoxCache path: $path');
+ if (_openCaches.containsKey(path)) {
+ _logger.fine('Cache already exists for path, returning it: $path');
+ return _openCaches[path]!;
+ }
+
try {
- Directory(path).createSync(recursive: true);
+ final directory = Directory(path);
+ if (!directory.existsSync()) {
+ Directory(path).createSync(recursive: true);
+ }
} catch (e) {
_logger.severe('Error creating ObjectCachePathDirectory: $e');
}
- _logger.info('ObjectBoxCache path: $path');
+
final store = await openStore(
- directory: path, macosApplicationGroup: 'T69YZGT58U.relatica');
- return ObjectBoxCache._create(store);
+ directory: path,
+ macosApplicationGroup: macOsGroupId,
+ );
+ final cache = ObjectBoxCache._create(store);
+ _openCaches[path] = cache;
+ _logger.fine('New cache created for path: $path');
+ return cache;
}
}
diff --git a/lib/globals.dart b/lib/globals.dart
index dbacb83..8e722d0 100644
--- a/lib/globals.dart
+++ b/lib/globals.dart
@@ -5,6 +5,8 @@ import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:uuid/uuid.dart';
+const macOsGroupId = 'T69YZGT58U.relatica';
+
final getIt = GetIt.instance;
String randomId() => const Uuid().v4().toString();
diff --git a/lib/models/auth/oauth_credentials.dart b/lib/models/auth/oauth_credentials.dart
index ca51148..5103490 100644
--- a/lib/models/auth/oauth_credentials.dart
+++ b/lib/models/auth/oauth_credentials.dart
@@ -95,7 +95,7 @@ class OAuthCredentials implements ICredentials {
final response = await http.post(idEndpoint, body: {
'client_name': 'Relatica',
'redirect_uris': '$redirectUrl',
- 'scopes': 'read write push',
+ 'scopes': 'read write follow push',
'website': 'https://myportal.social',
});
@@ -123,7 +123,7 @@ class OAuthCredentials implements ICredentials {
'response_type': 'code',
'client_id': clientId,
'redirect_uri': redirectUrl,
- 'scope': 'read write push',
+ 'scope': 'read write follow push',
});
try {
diff --git a/lib/screens/search_screen.dart b/lib/screens/search_screen.dart
index 620fadd..bd15ee3 100644
--- a/lib/screens/search_screen.dart
+++ b/lib/screens/search_screen.dart
@@ -182,8 +182,8 @@ class _SearchScreenState extends State {
),
),
),
- bottomNavigationBar: AppBottomNavBar(
- currentButton: NavBarButtons.contacts,
+ bottomNavigationBar: const AppBottomNavBar(
+ currentButton: NavBarButtons.search,
),
);
}
diff --git a/lib/services/notifications_manager.dart b/lib/services/notifications_manager.dart
index 818cafc..5877028 100644
--- a/lib/services/notifications_manager.dart
+++ b/lib/services/notifications_manager.dart
@@ -80,32 +80,52 @@ class NotificationsManager extends ChangeNotifier {
continue;
}
final page = _pm.pages[i];
- PagingData? pd;
if (i == 0) {
- if (page.next == null) {
- _logger.severe(
- "Expected first page to have a next page so can query on this page of data but doesn't exist.");
- continue;
- }
- final response = await _clientGetNotificationsRequest(page.next!);
- response.match(
- onSuccess: (response) => pd = response.previous,
- onError: (error) =>
- _logger.severe('Error getting previous page: $error'));
- if (pd == null && page.previous == null) {
- _logger.severe(
- 'Next page returned no results and no previous page so need to re-initalize');
- } else {
- final response = await _clientGetNotificationsRequest(pd!);
+ PagingData? pd;
+ bool initializedFirstPage = false;
+ if (page.next != null) {
+ final response = await _clientGetNotificationsRequest(page.next!);
response.match(
- onSuccess: (response) => pd = response.next,
+ onSuccess: (response) => pd = response.previous,
onError: (error) =>
_logger.severe('Error getting previous page: $error'));
+ if (pd != null) {
+ final response = await _clientGetNotificationsRequest(pd!);
+ response.match(
+ onSuccess: (response) {
+ initializedFirstPage = true;
+ notificationsFromRefresh.addAll(response.data);
+ },
+ onError: (error) =>
+ _logger.severe('Error getting previous page: $error'));
+ } else if (pd == null && page.previous != null) {
+ final response = await _clientGetNotificationsRequest(
+ page.previous!)
+ .andThenAsync((previousData) async => previousData.next !=
+ null
+ ? await _clientGetNotificationsRequest(previousData.next!)
+ : buildErrorResult(
+ type: ErrorType.rangeError,
+ message: 'No "next" page from previous data either'));
+ response.match(
+ onSuccess: (response) {
+ initializedFirstPage = true;
+ notificationsFromRefresh.addAll(response.data);
+ },
+ onError: (error) =>
+ _logger.severe('Error getting previous page: $error'));
+ } else if (pd == null && page.previous == null) {
+ _logger.severe(
+ 'Next page returned no results and no previous page so will need to re-initalize');
+ }
+ } else {
+ _logger.severe(
+ 'There is no next page to query so will be forced to reset');
}
- if (pd == null) {
+ if (!initializedFirstPage) {
_logger.severe(
- 'Previous and next page both returned nulls so need to reinitialize');
+ 'Unable to determine call to rebuild initial page so resetting');
_pm.clear();
final result = await _pm.initialize(initialPull);
result.andThenSuccess(
@@ -126,7 +146,7 @@ class NotificationsManager extends ChangeNotifier {
onSuccess: (response) =>
notificationsFromRefresh.addAll(response.data),
onError: (error) =>
- _logger.severe('Error getting previous page: $error'));
+ _logger.severe('Error getting next page: $error'));
}
}
diff --git a/lib/services/secrets_service.dart b/lib/services/secrets_service.dart
index 75789f1..8fc05ae 100644
--- a/lib/services/secrets_service.dart
+++ b/lib/services/secrets_service.dart
@@ -4,6 +4,7 @@ import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:result_monad/result_monad.dart';
+import '../globals.dart';
import '../models/auth/basic_credentials.dart';
import '../models/auth/credentials_intf.dart';
import '../models/auth/oauth_credentials.dart';
@@ -28,6 +29,7 @@ class SecretsService {
),
mOptions: MacOsOptions(
accountName: _storageAccountName,
+ groupId: macOsGroupId,
),
);
diff --git a/pubspec.yaml b/pubspec.yaml
index a2ff5fa..b0b8960 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -2,7 +2,7 @@ name: relatica
description: A mobile and desktop client for interacting with the Friendica social network
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
-version: 0.2.0+1
+version: 0.3.0+1
environment:
sdk: '>=2.18.2 <3.0.0'
diff --git a/screenshots/v0.3.0/linux/relatica_v0.3.0_drawer.png b/screenshots/v0.3.0/linux/relatica_v0.3.0_drawer.png
new file mode 100755
index 0000000..2cfb665
Binary files /dev/null and b/screenshots/v0.3.0/linux/relatica_v0.3.0_drawer.png differ
diff --git a/screenshots/v0.3.0/linux/relatica_v0.3.0_home.png b/screenshots/v0.3.0/linux/relatica_v0.3.0_home.png
new file mode 100755
index 0000000..966dc7b
Binary files /dev/null and b/screenshots/v0.3.0/linux/relatica_v0.3.0_home.png differ