kopia lustrzana https://gitlab.com/mysocialportal/relatica
Merge branch 'prep-v0.3.0' into 'main'
Prep v0.3.0 See merge request mysocialportal/relatica!28codemagic-setup
commit
a889037464
|
@ -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)
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
A Flutter application for interfacing with the Friendica social network.
|
||||
|
||||
<img src="screenshots/v0.2.0/linux/relatica_v0.2.0_home.png" alt="Relatica v0.2.0 on Linux Home Screen Screenshot" width="300px"/>
|
||||
<img src="screenshots/v0.3.0/linux/relatica_v0.3.0_home.png" alt="Relatica v0.3.0 on Linux Home Screen Screenshot" width="300px"/>
|
||||
|
||||
<img src="screenshots/v0.2.0/linux/relatica_v0.2.0_drawer.png" alt="Relatica v0.2.0 on Linux Home Expanded Drawer Screenshot" width="300px"/>
|
||||
<img src="screenshots/v0.3.0/linux/relatica_v0.3.0_drawer.png" alt="Relatica v0.3.0 on Linux Home Expanded Drawer Screenshot" width="300px"/>
|
||||
|
||||
## Project Objectives
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
10
install.md
10
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
|
||||
|
||||
|
|
|
@ -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 = <String, ObjectBoxCache>{};
|
||||
late final Store store;
|
||||
|
||||
ObjectBoxCache._create(this.store);
|
||||
|
||||
static Future<ObjectBoxCache> create(
|
||||
{String baseDir = 'objectboxcache', String? subDir}) async {
|
||||
static Future<ObjectBoxCache> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -182,8 +182,8 @@ class _SearchScreenState extends State<SearchScreen> {
|
|||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: AppBottomNavBar(
|
||||
currentButton: NavBarButtons.contacts,
|
||||
bottomNavigationBar: const AppBottomNavBar(
|
||||
currentButton: NavBarButtons.search,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
);
|
||||
|
||||
|
|
|
@ -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'
|
||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 49 KiB |
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 70 KiB |
Ładowanie…
Reference in New Issue