Compare commits

...

85 Commits

Author SHA1 Message Date
sk
8e840c2584 only download artifact "mastodos.apk" 2022-11-22 00:22:36 +01:00
sk
adf628de44 bump version 2022-11-21 23:14:58 +01:00
sk
7e4169644d update website 2022-11-21 23:11:33 +01:00
sk
e42988b51e Merge remote-tracking branch 'upstream/master' into fork 2022-11-21 21:58:55 +01:00
sk
7c2fd2b734 add script to get latest upstream commit 2022-11-21 21:58:35 +01:00
sk
569e4e13ea update readme 2022-11-21 21:57:52 +01:00
sk
b7b5785a97 Merge branch 'ui/profile-header-tweaks' into fork 2022-11-21 21:18:44 +01:00
sk
95d6e51ae0 Merge branch 'feature/copy-username' into fork 2022-11-21 20:58:25 +01:00
sk
fc43d919e5 tweak profile layout 2022-11-21 20:57:30 +01:00
sk
a8d19529cd Merge branch 'fix/lock-shifts-layout' into ui/profile-header-tweaks 2022-11-21 20:36:35 +01:00
sk
c2c44ab25e Merge branch 'fix/lock-shifts-layout' into feature/copy-username 2022-11-21 20:28:22 +01:00
sk
96a56873c3 add long-click to copy username 2022-11-21 20:14:45 +01:00
sk
0100967597 Merge branch 'fix/lock-shifts-layout' into fork 2022-11-21 20:12:17 +01:00
sk
5769b378e2 set 16dp lock on baseline 2022-11-21 20:12:04 +01:00
Grishka
2c61551e5c Add a tool to generate locales_config.xml 2022-11-21 22:04:30 +04:00
sk
c9b11a23a1 Merge branch 'ui/profile-header-tweaks' into fork 2022-11-21 18:26:56 +01:00
sk
456d05a489 close #66 2022-11-21 18:26:45 +01:00
sk
8ca7d9d7b4 Merge branch 'main' into ui/profile-header-tweaks 2022-11-21 18:10:56 +01:00
sk
2321549dca Merge branch 'main' into fork 2022-11-21 18:10:41 +01:00
sk
5ae96328d5 Merge branch 'feature/post-notifications-toggle' into fork 2022-11-21 18:08:27 +01:00
sk
dbf3da3629 hopefully fix #76 2022-11-21 18:08:16 +01:00
sk22
9a351de9b4 Update README.md 2022-11-21 17:22:12 +01:00
sk
f871fa6743 Merge branch 'fork' of github.com:sk22/mastodos into fork 2022-11-21 17:21:38 +01:00
sk
85f6441a56 make store icon pink 2022-11-21 17:21:27 +01:00
sk
dd8354f91b Merge branch 'clickable-boost-reply-line' into fork 2022-11-21 17:18:46 +01:00
sk
21d78de3cc make reply line match parent width 2022-11-21 17:18:38 +01:00
Grishka
158af27309 Fix #363 2022-11-21 18:36:33 +04:00
sk22
b0446af54a Merge pull request #75 from AiOO/translate-korean
Apply Korean translation for new strings
2022-11-21 15:33:15 +01:00
Ahn Kiwook
064f0155f6 Apply Korean translation for new strings 2022-11-21 23:03:50 +09:00
sk
fbf4522260 remove "debuggable" from release config
fixes #72
2022-11-21 14:11:46 +01:00
sk
8918bd5ce2 Merge branch 'main' into fork 2022-11-21 14:10:49 +01:00
Grishka
187693883c Fix #94
TODO support 4.0 filteing
2022-11-21 14:10:30 +04:00
sk
40868f90f9 bump version 2022-11-20 18:07:21 +01:00
sk
1f89acec34 Merge branch 'clickable-boost-reply-line' into fork 2022-11-20 17:46:28 +01:00
sk
d75ce99a68 make reblog/reply line clickable
fixes #62
see mastodon#287
2022-11-20 17:46:17 +01:00
sk
0a8846fa2a Merge branch 'main' into fork 2022-11-20 17:21:28 +01:00
sk
5253e2e24a Merge branch 'use-bold-boost-icon' into fork 2022-11-20 17:11:42 +01:00
sk
3565223611 use bold boost icon
fixes #363
2022-11-20 17:09:23 +01:00
sk
2343d7a046 disable updater for debug build 2022-11-20 16:10:01 +01:00
sk
8256fbadb6 make release debuggable 2022-11-20 16:09:42 +01:00
Grishka
b898dc010e Show an error if a server has signups closed
closes #377
2022-11-20 13:36:23 +04:00
Grishka
de369633ec Fix #386 2022-11-20 12:54:56 +04:00
Gregory K
3f075eab13 Merge pull request #387 from sk22/fix-screenreader-middle-dot
Omit “middle dot” for screen reader
2022-11-20 07:54:06 +03:00
sk
96e5f854a5 Merge branch 'ui/profile-header-tweaks' into fork 2022-11-20 02:22:21 +01:00
sk
0f5211f718 change header height 2022-11-20 02:20:13 +01:00
sk
480915f377 change headerless header color 2022-11-20 02:20:01 +01:00
sk
15d559ad6a Revert "Updated Catalan strings"
This reverts commit 2d710cb558.
2022-11-20 02:02:29 +01:00
sk
3b7a6e9385 bump version 2022-11-20 01:37:02 +01:00
sk
314a15973c Merge branch 'fix-screenreader-middle-dot' into fork 2022-11-20 01:35:40 +01:00
sk
e99917945a omit middle dot for screen reader 2022-11-20 01:34:02 +01:00
sk
d3ba8a4d0f Merge branch 'fork' of github.com:sk22/mastodos into fork 2022-11-20 01:22:03 +01:00
sk22
9162b31ac1 Merge pull request #58 from rbnval/patch-1
Updated Catalan strings
2022-11-20 01:21:49 +01:00
sk22
51a80f3e03 remove whitespaces 2022-11-20 01:21:32 +01:00
sk
a8c49b59f6 Merge branch 'ui/larger-post-buttons' into fork 2022-11-20 01:16:39 +01:00
sk
c79942c13f make three-dot/visibility buttons larger
see mastodon#337
2022-11-20 01:15:53 +01:00
rbnval
da121495c0 Update strings.xml 2022-11-20 01:14:46 +01:00
rbnval
2d710cb558 Updated Catalan strings 2022-11-20 01:03:50 +01:00
sk
f0a51a15a9 Merge branch 'feature/follow_hashtags' into fork 2022-11-20 00:18:00 +01:00
sk
ae68b1e646 add error check 2022-11-20 00:17:16 +01:00
sk
5da58d7834 Merge branch 'main' into feature/follow_hashtags 2022-11-20 00:04:35 +01:00
sk
24023e9843 Merge branch 'true-black-improvements' into fork 2022-11-20 00:02:21 +01:00
sk
29d9871e77 improve true black styles 2022-11-20 00:01:53 +01:00
sk
32d182f03a Merge branch 'feature/display-reply-visibility' into fork 2022-11-19 23:44:07 +01:00
sk
da4f54751e don't display when visibility is unknown 2022-11-19 23:43:52 +01:00
sk
393c538464 bump version 2022-11-19 22:54:21 +01:00
sk
ddcf61dc95 Merge branch 'true-black-improvements' into fork 2022-11-19 22:41:50 +01:00
sk
5b70c035d2 fix #54, #55 2022-11-19 22:40:13 +01:00
sk
289564381d bump version 2022-11-19 20:41:27 +01:00
sk
3fbcce8570 Merge branch 'true-black-improvements' into fork 2022-11-19 20:38:16 +01:00
sk
505b755df6 use @color/black instead of #000
to avoid crash when getting null resource ID
2022-11-19 20:38:01 +01:00
sk
4b9618cad5 bump version 2022-11-19 20:18:50 +01:00
sk
e7b0e022d6 Merge branch 'main' into fork 2022-11-19 20:18:20 +01:00
sk
7ffc58d52c update readme 2022-11-19 20:17:51 +01:00
Grishka
30151cafc2 Yes I can flip that to true 2022-11-19 23:13:50 +04:00
sk
d0ce157069 Merge branch 'feature/posts-notifications-tab' into fork 2022-11-19 20:13:16 +01:00
sk
be7d65989d add posts notifications tab
closes #38
2022-11-19 20:12:52 +01:00
sk
08656a2678 Merge branch 'feature/display-reply-visibility' into fork 2022-11-19 19:39:26 +01:00
sk
b0f76739ba implement showing original visibility on reply
closes #41
2022-11-19 19:39:09 +01:00
sk
a09efd084e Merge branch 'true-black-improvements' into fork 2022-11-19 16:36:34 +01:00
sk
0bb85d71e4 improve real black mode
closes #48, improves upon mastodon#84
2022-11-19 16:36:12 +01:00
thomas
7248ab9801 true dark improvement 2022-11-19 16:31:26 +01:00
sk
cd4d83e139 Merge branch 'settings/disable-marquee' into fork 2022-11-19 16:11:41 +01:00
sk
f1f7c1341c add option to disable scrolling title bars
closes #50
as mentioned in mastodon#305
2022-11-19 16:09:45 +01:00
sk
a7ab6945f9 Merge branch 'feature/lists' into fork 2022-11-19 15:48:59 +01:00
sk
896583aeec fix compose button prepending list id
closes #51
2022-11-19 15:48:47 +01:00
48 changed files with 430 additions and 120 deletions

View File

@@ -6,8 +6,11 @@
[![Download latest release](https://img.shields.io/badge/dynamic/json?color=d92aad&label=download%20apk&query=%24.tag_name&url=https%3A%2F%2Fapi.github.com%2Frepos%2Fsk22%2Fmastodon-android-fork%2Freleases%2Flatest&style=for-the-badge)](https://github.com/sk22/mastodos/releases/latest/download/mastodos.apk)
![A pinker version of the official Mastodon banner](img/banner.png)
---
## Key features
### **Unlisted posting**
@@ -52,6 +55,28 @@ To install this app on your Android device, download the [latest release from Gi
Mastodos makes use of [Mastodon for Android](https://github.com/mastodon/mastodon-android)s automatic update checker. Mastodos will check for new updates available on GitHub and offer to download and install them. You can also manually press “Check for updates” at the bottom of the settings page!
### Other sources
* **[Izzy's F-Droid repository](https://apt.izzysoft.de/fdroid/repo)**: https://apt.izzysoft.de/fdroid/index/apk/org.joinmastodon.android.sk
---
## Release variants
All downloads can be found on the [Releases](https://github.com/sk22/mastodos/releases) page.
**`mastodos.apk`**
Variant with an integrated updater. If you download Mastodos from here (and not from an app store), just download the regular `mastodos.apk`.
**`mastodon-1234abc.apk`**
This is an **unmodified version** of the official [Mastodon for Android](https://github.com/mastodon/mastodon-android) app the respective Mastodos release is based on. Should you find any bugs in Mastodos (which you will), try to see if it occurs with this variant, too. The last 7 digits of the file name are important to know which version of the official app you're using.
<!-- **`mastodon-fdroid.apk`**
Variant without the integrated updater. This is the variant to be published to F-Droid.org where an integrated updater is not necessary. -->
---
## Detailed changes
@@ -74,6 +99,10 @@ Mastodos makes use of [Mastodon for Android](https://github.com/mastodon/mastodo
* [List favorited posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/favs-list)
* [Accept/reject follow requests](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/follow-requests)
* [Display content warning title above text](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/cw-above-text)
* [Add notifications tab for posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/posts-notifications-tab)
* [Show visibility of original post when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/display-reply-visibility)
* [Clickable reply/boost line above posts](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:clickable-boost-reply-line)
* [Long-click to copy username from profile](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/copy-username)
### Behavior
@@ -81,9 +110,15 @@ Mastodos makes use of [Mastodon for Android](https://github.com/mastodon/mastodo
* [Always preserve content warnings when replying](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/always-preserve-cw) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/113))
* [Display full image when adding image description](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
* [Set spoiler height independently to content height](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:spoiler-height-independent) ([Closes issue](https://github.com/mastodon/mastodon-android/issues/166))
* [Custom extended footer redesign](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:compact-extended-footer)
* [Option to hide interaction numbers](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:settings/hide-interaction-numbers)
* [Option to always reveal content warnings](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:feature/cw-above-text)
* [Option to disable scrolling title bars](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:settings/disable-marquee)
### Visual
* [Custom extended footer redesign](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:compact-extended-footer)
* [Improvements to the true black mode](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:true-black-improvements)
* [Profile header tweaks](https://github.com/mastodon/mastodon-android/compare/master...sk22:mastodos:ui/profile-header-tweaks)
### Branding
@@ -91,7 +126,7 @@ Mastodos makes use of [Mastodon for Android](https://github.com/mastodon/mastodo
* Pink primary color
* Custom icon: Modulate upstream icon using ImageMagick
```bash
mogrify -modulate 90,100,140 mastodon/src/main/res/mipmap-*/ic_launcher*.png
mogrify -modulate 90,100,140 mastodon/src/main/res/mipmap-*/ic_launcher*.png mastodon/src/main/ic_launcher-playstore.png
```
## Building
@@ -105,3 +140,7 @@ As this app is using Java 17 features, you need JDK 17 or newer to build it. Oth
## License
This project is released under the [GPL-3 License](./LICENSE).
## Links
<a rel="me" href="https://floss.social/@mastodos">@mastodos@floss.social</a>

View File

@@ -1,2 +1,2 @@
title: Mastodos
theme: minima
layout: default

17
_layouts/default.html Normal file
View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mastodos</title>
<link rel="icon" href="mastodon/src/main/res/mipmap-mdpi/ic_launcher_round.png">
<link rel="me" href="https://floss.social/@mastodon">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.min.css">
</head>
<body class="markdown-body">
<div style="margin: 0 auto; max-width: 45rem; padding: 2rem 1rem">
{{ content }}
</div>
</body>
</html>

3
get-upstream-commit.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
git rev-parse --short --verify upstream/master

BIN
img/banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 KiB

View File

@@ -9,8 +9,8 @@ android {
applicationId "org.joinmastodon.android.sk"
minSdk 23
targetSdk 33
versionCode 41
versionName "1.1.4+fork.41"
versionCode 47
versionName "1.1.4+fork.47"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resConfigs "en", "ar-rSA", "bs-rBA", "ca-rES", "cs-rCZ", "de-rDE", "el-rGR", "es-rES",
"eu-rES", "fi-rFI", "fr-rFR", "gl-rES", "hr-rHR", "hy-rAM", "it-rIT", "iw-rIL",
@@ -20,12 +20,13 @@ android {
buildTypes {
release {
minifyEnabled true
shrinkResources true
// minifyEnabled true
// shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug{
debuggable true
versionNameSuffix '-debug'
}
appcenterPrivateBeta{
initWith release

View File

@@ -139,12 +139,12 @@ public class GithubSelfUpdaterImpl extends GithubSelfUpdater{
curForkNumber=Integer.parseInt(matcher.group(4));
long newVersion=((long)newMajor << 32) | ((long)newMinor << 16) | newRevision;
long curVersion=((long)curMajor << 32) | ((long)curMinor << 16) | curRevision;
if(newVersion>curVersion || newForkNumber>curForkNumber || BuildConfig.DEBUG){
if(newVersion>curVersion || newForkNumber>curForkNumber){
String version=newMajor+"."+newMinor+"."+newRevision+"+fork."+newForkNumber;
Log.d(TAG, "actuallyCheckForUpdates: new version: "+version);
for(JsonElement el:obj.getAsJsonArray("assets")){
JsonObject asset=el.getAsJsonObject();
if("application/vnd.android.package-archive".equals(asset.get("content_type").getAsString()) && "uploaded".equals(asset.get("state").getAsString())){
if("mastodos.apk".equals(asset.get("name")) && "application/vnd.android.package-archive".equals(asset.get("content_type").getAsString()) && "uploaded".equals(asset.get("state").getAsString())){
long size=asset.get("size").getAsLong();
String url=asset.get("browser_download_url").getAsString();

View File

@@ -8,6 +8,7 @@
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<permission android:name="${applicationId}.permission.C2D_MESSAGE" android:protectionLevel="signature"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -12,9 +12,10 @@ public class GlobalUserPreferences{
public static boolean loadNewPosts;
public static boolean showInteractionCounts;
public static boolean alwaysExpandContentWarnings;
public static boolean disableMarquee;
public static ThemePreference theme;
private static SharedPreferences getPrefs(){
private static SharedPreferences getPrefs(){
return MastodonApp.context.getSharedPreferences("global", Context.MODE_PRIVATE);
}
@@ -28,6 +29,7 @@ public class GlobalUserPreferences{
loadNewPosts=prefs.getBoolean("loadNewPosts", true);
showInteractionCounts=prefs.getBoolean("showInteractionCounts", false);
alwaysExpandContentWarnings=prefs.getBoolean("alwaysExpandContentWarnings", false);
disableMarquee=prefs.getBoolean("disableMarquee", false);
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
}
@@ -41,6 +43,7 @@ public class GlobalUserPreferences{
.putBoolean("trueBlackTheme", trueBlackTheme)
.putBoolean("showInteractionCounts", showInteractionCounts)
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
.putBoolean("disableMarquee", disableMarquee)
.putInt("theme", theme.ordinal())
.apply();
}

View File

@@ -35,7 +35,7 @@ import me.grishka.appkit.utils.WorkerThread;
public class CacheController{
private static final String TAG="CacheController";
private static final int DB_VERSION=2;
private static final int DB_VERSION=3;
private static final WorkerThread databaseThread=new WorkerThread("databaseThread");
private static final Handler uiHandler=new Handler(Looper.getMainLooper());
@@ -73,7 +73,7 @@ public class CacheController{
status.hasGapAfter=((flags & POST_FLAG_GAP_AFTER)!=0);
newMaxID=status.id;
for(Filter filter:filters){
if(filter.matches(status.getContentStatus().content))
if(filter.matches(status))
continue outer;
}
result.add(status);
@@ -126,14 +126,15 @@ public class CacheController{
});
}
public void getNotifications(String maxID, int count, boolean onlyMentions, boolean forceReload, Callback<PaginatedResponse<List<Notification>>> callback){
public void getNotifications(String maxID, int count, boolean onlyMentions, boolean onlyPosts, boolean forceReload, Callback<PaginatedResponse<List<Notification>>> callback){
cancelDelayedClose();
databaseThread.postRunnable(()->{
try{
List<Filter> filters=AccountSessionManager.getInstance().getAccount(accountID).wordFilters.stream().filter(f->f.context.contains(Filter.FilterContext.NOTIFICATIONS)).collect(Collectors.toList());
if(!forceReload){
SQLiteDatabase db=getOrOpenDatabase();
try(Cursor cursor=db.query(onlyMentions ? "notifications_mentions" : "notifications_all", new String[]{"json"}, maxID==null ? null : "`id`<?", maxID==null ? null : new String[]{maxID}, null, null, "`id` DESC", count+"")){
String table=onlyPosts ? "notifications_posts" : onlyMentions ? "notifications_mentions" : "notifications_all";
try(Cursor cursor=db.query(table, new String[]{"json"}, maxID==null ? null : "`id`<?", maxID==null ? null : new String[]{maxID}, null, null, "`id` DESC", count+"")){
if(cursor.getCount()==count){
ArrayList<Notification> result=new ArrayList<>();
cursor.moveToFirst();
@@ -145,7 +146,7 @@ public class CacheController{
newMaxID=ntf.id;
if(ntf.status!=null){
for(Filter filter:filters){
if(filter.matches(ntf.status.getContentStatus().content))
if(filter.matches(ntf.status))
continue outer;
}
}
@@ -159,21 +160,21 @@ public class CacheController{
Log.w(TAG, "getNotifications: corrupted notification object in database", x);
}
}
new GetNotifications(maxID, count, onlyMentions ? EnumSet.of(Notification.Type.MENTION): EnumSet.allOf(Notification.Type.class))
new GetNotifications(maxID, count, onlyPosts ? EnumSet.of(Notification.Type.STATUS) : onlyMentions ? EnumSet.of(Notification.Type.MENTION): EnumSet.allOf(Notification.Type.class))
.setCallback(new Callback<>(){
@Override
public void onSuccess(List<Notification> result){
callback.onSuccess(new PaginatedResponse<>(result.stream().filter(ntf->{
if(ntf.status!=null){
for(Filter filter:filters){
if(filter.matches(ntf.status.getContentStatus().content)){
if(filter.matches(ntf.status)){
return false;
}
}
}
return true;
}).collect(Collectors.toList()), result.isEmpty() ? null : result.get(result.size()-1).id));
putNotifications(result, onlyMentions, maxID==null);
putNotifications(result, onlyMentions, onlyPosts, maxID==null);
}
@Override
@@ -191,9 +192,9 @@ public class CacheController{
}, 0);
}
private void putNotifications(List<Notification> notifications, boolean onlyMentions, boolean clear){
private void putNotifications(List<Notification> notifications, boolean onlyMentions, boolean onlyPosts, boolean clear){
runOnDbThread((db)->{
String table=onlyMentions ? "notifications_mentions" : "notifications_all";
String table=onlyPosts ? "notifications_posts" : onlyMentions ? "notifications_mentions" : "notifications_all";
if(clear)
db.delete(table, null, null);
ContentValues values=new ContentValues(3);
@@ -317,6 +318,7 @@ public class CacheController{
`type` INTEGER NOT NULL
)""");
createRecentSearchesTable(db);
createPostsNotificationsTable(db);
}
@Override
@@ -324,6 +326,9 @@ public class CacheController{
if(oldVersion==1){
createRecentSearchesTable(db);
}
if(oldVersion==2){
createPostsNotificationsTable(db);
}
}
private void createRecentSearchesTable(SQLiteDatabase db){
@@ -334,6 +339,16 @@ public class CacheController{
`time` INTEGER NOT NULL
)""");
}
private void createPostsNotificationsTable(SQLiteDatabase db){
db.execSQL("""
CREATE TABLE `notifications_posts` (
`id` VARCHAR(25) NOT NULL PRIMARY KEY,
`json` TEXT NOT NULL,
`flags` INTEGER NOT NULL DEFAULT 0,
`type` INTEGER NOT NULL
)""");
}
}
@FunctionalInterface

View File

@@ -19,6 +19,7 @@ import android.view.WindowInsets;
import android.widget.Toolbar;
import org.joinmastodon.android.E;
import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
import org.joinmastodon.android.api.requests.polls.SubmitPollVote;
@@ -81,6 +82,10 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(GlobalUserPreferences.disableMarquee){
setTitleMarqueeEnabled(false);
setSubtitleMarqueeEnabled(false);
}
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
setRetainInstance(true);
}

View File

@@ -13,6 +13,7 @@ import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.RenderEffect;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.icu.text.BreakIterator;
import android.media.MediaMetadataRetriever;
@@ -502,6 +503,24 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
spoilerEdit.addTextChangedListener(new SimpleTextWatcher(e->updateCharCounter()));
if(replyTo!=null){
replyText.setText(getString(R.string.in_reply_to, replyTo.account.displayName));
int visibilityNameRes = switch (statusVisibility) {
case PUBLIC -> R.string.visibility_public;
case UNLISTED -> R.string.visibility_unlisted;
case PRIVATE -> R.string.visibility_followers_only;
case DIRECT -> R.string.visibility_private;
};
replyText.setContentDescription(getString(R.string.in_reply_to, replyTo.account.displayName) + ". " + getString(R.string.post_visibility) + ": " + getString(visibilityNameRes));
Drawable visibilityIcon = getActivity().getDrawable(switch(statusVisibility){
case PUBLIC -> R.drawable.ic_fluent_earth_20_regular;
case UNLISTED -> R.drawable.ic_fluent_people_community_20_regular;
case PRIVATE -> R.drawable.ic_fluent_people_checkmark_20_regular;
case DIRECT -> R.drawable.ic_at_symbol;
});
visibilityIcon.setBounds(0, 0, V.dp(20), V.dp(20));
Drawable replyArrow = getActivity().getDrawable(R.drawable.ic_fluent_arrow_reply_20_filled);
replyArrow.setBounds(0, 0, V.dp(20), V.dp(20));
replyText.setCompoundDrawables(replyArrow, null, visibilityIcon, null);
ArrayList<String> mentions=new ArrayList<>();
String ownID=AccountSessionManager.getInstance().getAccount(accountID).self.id;
if(!replyTo.account.id.equals(ownID))

View File

@@ -66,8 +66,8 @@ public class HashtagTimelineFragment extends StatusListFragment{
new SetHashtagFollowed(hashtag, following).setCallback(new Callback<>() {
@Override
public void onSuccess(Hashtag i) {
if (i.following == following) Toast.makeText(getActivity(), getString(i.following ? R.string.followed_user : R.string.unfollowed_user, "#" + i.name), Toast.LENGTH_SHORT).show();
updateFollowingState(i.following);
Toast.makeText(getActivity(), getString(i.following ? R.string.followed_user : R.string.unfollowed_user, "#" + i.name), Toast.LENGTH_SHORT).show();
}
@Override

View File

@@ -268,7 +268,7 @@ public class HomeTimelineFragment extends StatusListFragment{
if(idsBelowGap.contains(s.id))
break;
for(Filter filter:filters){
if(filter.matches(s.getContentStatus().content)){
if(filter.matches(s)){
continue outer;
}
}

View File

@@ -41,6 +41,7 @@ public class ListTimelineFragment extends StatusListFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
// TODO: implement edit, delete
// inflater.inflate(R.menu.list, menu);
}
@@ -73,7 +74,6 @@ public class ListTimelineFragment extends StatusListFragment {
private void onFabClick(View v){
Bundle args=new Bundle();
args.putString("account", accountID);
args.putString("prefilledText", listID+' ');
Nav.go(getActivity(), ComposeFragment.class, args);
}

View File

@@ -44,7 +44,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
private FrameLayout[] tabViews;
private TabLayoutMediator tabLayoutMediator;
private NotificationsListFragment allNotificationsFragment, mentionsFragment;
private NotificationsListFragment allNotificationsFragment, mentionsFragment, postsFragment;
private String accountID;
@@ -92,12 +92,13 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
tabLayout=view.findViewById(R.id.tabbar);
pager=view.findViewById(R.id.pager);
tabViews=new FrameLayout[2];
tabViews=new FrameLayout[3];
for(int i=0;i<tabViews.length;i++){
FrameLayout tabView=new FrameLayout(getActivity());
tabView.setId(switch(i){
case 0 -> R.id.notifications_all;
case 1 -> R.id.notifications_mentions;
case 2 -> R.id.notifications_posts;
default -> throw new IllegalStateException("Unexpected value: "+i);
});
tabView.setVisibility(View.GONE);
@@ -136,9 +137,15 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
mentionsFragment=new NotificationsListFragment();
mentionsFragment.setArguments(args);
args=new Bundle(args);
args.putBoolean("onlyPosts", true);
postsFragment=new NotificationsListFragment();
postsFragment.setArguments(args);
getChildFragmentManager().beginTransaction()
.add(R.id.notifications_all, allNotificationsFragment)
.add(R.id.notifications_mentions, mentionsFragment)
.add(R.id.notifications_posts, postsFragment)
.commit();
}
@@ -148,6 +155,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
tab.setText(switch(position){
case 0 -> R.string.all_notifications;
case 1 -> R.string.mentions;
case 2 -> R.string.posts;
default -> throw new IllegalStateException("Unexpected value: "+position);
});
tab.view.textView.setAllCaps(true);
@@ -196,6 +204,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
return switch(page){
case 0 -> allNotificationsFragment;
case 1 -> mentionsFragment;
case 2 -> postsFragment;
default -> throw new IllegalStateException("Unexpected value: "+page);
};
}
@@ -216,7 +225,7 @@ public class NotificationsFragment extends MastodonToolbarFragment implements Sc
@Override
public int getItemCount(){
return 2;
return 3;
}
@Override

View File

@@ -35,6 +35,7 @@ import me.grishka.appkit.utils.V;
public class NotificationsListFragment extends BaseStatusListFragment<Notification>{
private boolean onlyMentions;
private boolean onlyPosts;
private String maxID;
@Override
@@ -53,6 +54,7 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
public void onAttach(Activity activity){
super.onAttach(activity);
onlyMentions=getArguments().getBoolean("onlyMentions", false);
onlyPosts=getArguments().getBoolean("onlyPosts", false);
}
@Override
@@ -106,7 +108,7 @@ public class NotificationsListFragment extends BaseStatusListFragment<Notificati
protected void doLoadData(int offset, int count){
AccountSessionManager.getInstance()
.getAccount(accountID).getCacheController()
.getNotifications(offset>0 ? maxID : null, count, onlyMentions, refreshing, new SimpleCallback<>(this){
.getNotifications(offset>0 ? maxID : null, count, onlyMentions, onlyPosts, refreshing, new SimpleCallback<>(this){
@Override
public void onSuccess(PaginatedResponse<List<Notification>> result){
if(getActivity()==null)

View File

@@ -1,11 +1,16 @@
package org.joinmastodon.android.fragments;
import static android.content.Context.CLIPBOARD_SERVICE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.app.Activity;
import android.app.Fragment;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Outline;
@@ -14,6 +19,8 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.style.ImageSpan;
@@ -31,9 +38,11 @@ import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import org.joinmastodon.android.GlobalUserPreferences;
@@ -435,15 +444,25 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
ssb.append(AccountSessionManager.getInstance().getAccount(accountID).domain);
}
ssb.append(" ");
Drawable lock=username.getResources().getDrawable(R.drawable.ic_fluent_lock_closed_20_filled, getActivity().getTheme()).mutate();
Drawable lock=username.getResources().getDrawable(R.drawable.ic_lock, getActivity().getTheme()).mutate();
lock.setBounds(0, 0, lock.getIntrinsicWidth(), lock.getIntrinsicHeight());
lock.setTint(username.getCurrentTextColor());
ssb.append(getString(R.string.manually_approves_followers), new ImageSpan(lock, ImageSpan.ALIGN_BOTTOM), 0);
ssb.append(getString(R.string.manually_approves_followers), new ImageSpan(lock, ImageSpan.ALIGN_BASELINE), 0);
username.setText(ssb);
}else{
// noinspection SetTextI18n
username.setText('@'+account.acct+(isSelf ? ('@'+AccountSessionManager.getInstance().getAccount(accountID).domain) : ""));
}
username.setOnLongClickListener(l->{
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE);
Vibrator v = (Vibrator) getActivity().getSystemService(Context.VIBRATOR_SERVICE);
ClipData clip = ClipData.newPlainText("Username", '@'+account.acct+'@'+AccountSessionManager.getInstance().getAccount(accountID).domain);
clipboard.setPrimaryClip(clip);
Toast.makeText(getActivity(), R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) v.vibrate(VibrationEffect.createOneShot(50, VibrationEffect.DEFAULT_AMPLITUDE));
else v.vibrate(50);
return true;
});
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
if(TextUtils.isEmpty(parsedBio)){
bio.setVisibility(View.GONE);
@@ -648,7 +667,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
notifyProgress.setIndeterminateTintList(notifyButton.getTextColors());
followsYouView.setVisibility(relationship.followedBy ? View.VISIBLE : View.GONE);
notifyButton.setSelected(relationship.notifying);
notifyButton.setContentDescription(getString(relationship.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username));
if (getActivity() != null) notifyButton.setContentDescription(getString(relationship.notifying ? R.string.user_post_notifications_on : R.string.user_post_notifications_off, '@'+account.username));
}
private void onScrollChanged(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY){

View File

@@ -94,6 +94,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
items.add(new HeaderItem(R.string.settings_theme));
items.add(themeItem=new ThemeItem());
items.add(new SwitchItem(R.string.theme_true_black, R.drawable.ic_fluent_dark_theme_24_regular, GlobalUserPreferences.trueBlackTheme, this::onTrueBlackThemeChanged));
items.add(new SwitchItem(R.string.disable_marquee, R.drawable.ic_fluent_text_more_24_regular, GlobalUserPreferences.disableMarquee, i->{
GlobalUserPreferences.disableMarquee=i.checked;
GlobalUserPreferences.save();
}));
items.add(new HeaderItem(R.string.settings_behavior));
items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{

View File

@@ -139,7 +139,7 @@ public class StatusEditHistoryFragment extends StatusListFragment{
action=getString(R.string.edit_multiple_changed);
}
}
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" · "+date, Collections.emptyList(), 0));
items.add(0, new ReblogOrReplyLineStatusDisplayItem(s.id, this, action+" · "+date, Collections.emptyList(), 0, null));
}
return items;
}

View File

@@ -97,7 +97,7 @@ public class ThreadFragment extends StatusListFragment{
return statuses;
return statuses.stream().filter(status->{
for(Filter filter:filters){
if(filter.matches(status.getContentStatus().content))
if(filter.matches(status))
return false;
}
return true;

View File

@@ -53,6 +53,7 @@ import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import javax.xml.parsers.DocumentBuilderFactory;
@@ -295,6 +296,14 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
private void proceedWithAuthOrSignup(Instance instance){
getActivity().getSystemService(InputMethodManager.class).hideSoftInputFromWindow(contentView.getWindowToken(), 0);
if(isSignup){
if(!instance.registrations){
new M3AlertDialogBuilder(getActivity())
.setTitle(R.string.error)
.setMessage(R.string.instance_signup_closed)
.setPositiveButton(R.string.ok, null)
.show();
return;
}
Bundle args=new Bundle();
args.putParcelable("instance", Parcels.wrap(instance));
Nav.go(getActivity(), InstanceRulesFragment.class, args);
@@ -478,7 +487,7 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment<CatalogInstanc
instanceProgressDialog=null;
proceedWithAuthOrSignup(result);
}
if(domain.equals(currentSearchQuery) || currentSearchQuery.equals(redirects.get(domain)) || currentSearchQuery.equals(redirectsInverse.get(domain))){
if(Objects.equals(domain, currentSearchQuery) || Objects.equals(currentSearchQuery, redirects.get(domain)) || Objects.equals(currentSearchQuery, redirectsInverse.get(domain))){
boolean found=false;
for(CatalogInstance ci:filteredData){
if(ci.domain.equals(domain)){

View File

@@ -102,7 +102,7 @@ public class ReportCommentFragment extends MastodonToolbarFragment{
ReportReason reason=ReportReason.valueOf(getArguments().getString("reason"));
ArrayList<String> statusIDs=getArguments().getStringArrayList("statusIDs");
ArrayList<String> ruleIDs=getArguments().getStringArrayList("ruleIDs");
new SendReport(reportAccount.id, reason, statusIDs, ruleIDs, v.getId()==R.id.btn_back ? null : commentEdit.getText().toString(), false)
new SendReport(reportAccount.id, reason, statusIDs, ruleIDs, v.getId()==R.id.btn_back ? null : commentEdit.getText().toString(), true)
.setCallback(new Callback<>(){
@Override
public void onSuccess(Object result){

View File

@@ -50,6 +50,10 @@ public class Filter extends BaseModel{
return pattern.matcher(text).find();
}
public boolean matches(Status status){
return matches(status.getContentStatus().getStrippedText());
}
@Override
public String toString(){
return "Filter{"+

View File

@@ -4,6 +4,7 @@ import org.joinmastodon.android.GlobalUserPreferences;
import org.joinmastodon.android.api.ObjectValidationException;
import org.joinmastodon.android.api.RequiredField;
import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.parceler.Parcel;
import java.time.Instant;
@@ -57,6 +58,7 @@ public class Status extends BaseModel implements DisplayItemsParent{
public transient boolean spoilerRevealed;
public transient boolean hasGapAfter;
private transient String strippedText;
@Override
public void postprocess() throws ObjectValidationException{
@@ -134,4 +136,10 @@ public class Status extends BaseModel implements DisplayItemsParent{
public Status getContentStatus(){
return reblog!=null ? reblog : this;
}
public String getStrippedText(){
if(strippedText==null)
strippedText=HtmlParser.strip(content);
return strippedText;
}
}

View File

@@ -4,6 +4,7 @@ import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.SpannableStringBuilder;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
@@ -17,6 +18,8 @@ import org.joinmastodon.android.ui.utils.UiUtils;
import java.util.List;
import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
@@ -25,14 +28,16 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
@DrawableRes
private int icon;
private CustomEmojiHelper emojiHelper=new CustomEmojiHelper();
private View.OnClickListener handleClick;
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon){
public ReblogOrReplyLineStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, CharSequence text, List<Emoji> emojis, @DrawableRes int icon, @Nullable View.OnClickListener handleClick){
super(parentID, parentFragment);
SpannableStringBuilder ssb=new SpannableStringBuilder(text);
HtmlParser.parseCustomEmoji(ssb, emojis);
this.text=ssb;
emojiHelper.setText(ssb);
this.icon=icon;
this.handleClick=handleClick;
}
@Override
@@ -61,6 +66,7 @@ public class ReblogOrReplyLineStatusDisplayItem extends StatusDisplayItem{
public void onBind(ReblogOrReplyLineStatusDisplayItem item){
text.setText(item.text);
text.setCompoundDrawablesRelativeWithIntrinsicBounds(item.icon, 0, 0, 0);
if(item.handleClick!=null) text.setOnClickListener(item.handleClick);
if(Build.VERSION.SDK_INT<Build.VERSION_CODES.N)
UiUtils.fixCompoundDrawableTintOnAndroid6(text);
}

View File

@@ -2,12 +2,14 @@ package org.joinmastodon.android.ui.displayitems;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import org.joinmastodon.android.R;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.fragments.ProfileFragment;
import org.joinmastodon.android.fragments.ThreadFragment;
import org.joinmastodon.android.model.Account;
import org.joinmastodon.android.model.Attachment;
@@ -16,6 +18,7 @@ import org.joinmastodon.android.model.Poll;
import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.ui.PhotoLayoutHelper;
import org.joinmastodon.android.ui.text.HtmlParser;
import org.parceler.Parcels;
import java.util.ArrayList;
import java.util.List;
@@ -23,6 +26,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import me.grishka.appkit.Nav;
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
import me.grishka.appkit.utils.BindableViewHolder;
import me.grishka.appkit.views.UsableRecyclerView;
@@ -73,11 +77,19 @@ public abstract class StatusDisplayItem{
String parentID=parentObject.getID();
ArrayList<StatusDisplayItem> items=new ArrayList<>();
Status statusForContent=status.getContentStatus();
Bundle args=new Bundle();
args.putString("account", accountID);
if(status.reblog!=null){
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20_filled));
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.user_boosted, status.account.displayName), status.account.emojis, R.drawable.ic_fluent_arrow_repeat_all_20_filled, i->{
args.putParcelable("profileAccount", Parcels.wrap(status.account));
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
}));
}else if(status.inReplyToAccountId!=null && knownAccounts.containsKey(status.inReplyToAccountId)){
Account account=Objects.requireNonNull(knownAccounts.get(status.inReplyToAccountId));
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_fluent_arrow_reply_20_filled));
items.add(new ReblogOrReplyLineStatusDisplayItem(parentID, fragment, fragment.getString(R.string.in_reply_to, account.displayName), account.emojis, R.drawable.ic_fluent_arrow_reply_20_filled, i->{
args.putParcelable("profileAccount", Parcels.wrap(account));
Nav.go(fragment.getActivity(), ProfileFragment.class, args);
}));
}
HeaderStatusDisplayItem header;
items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null));

View File

@@ -21,9 +21,8 @@ public class StatusFilterPredicate implements Predicate<Status>{
@Override
public boolean test(Status status){
CharSequence content=status.getContentStatus().content;
for(Filter filter:filters){
if(filter.matches(content))
if(filter.matches(status))
return false;
}
return true;

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?colorBackgroundLightest"/>
<solid android:color="?colorBackgroundPopup"/>
<corners android:radius="10dp"/>
<padding android:top="8dp" android:bottom="8dp"/>
</shape>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/ic_fluent_arrow_repeat_all_24_filled"/>
<item android:state_enabled="true" android:drawable="@drawable/ic_fluent_arrow_repeat_all_24_regular"/>
<item android:drawable="@drawable/ic_fluent_arrow_repeat_all_off_24_regular"/>
</selector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M14.712 2.289L14.625 2.21c-0.392-0.31-0.964-0.285-1.327 0.078L13.22 2.376c-0.31 0.392-0.285 0.964 0.078 1.326l1.299 1.297H8.999L8.76 5.003C5.004 5.13 2 8.211 2 11.993c0 1.445 0.438 2.788 1.189 3.899C3.37 16.143 3.666 16.307 4 16.307c0.552 0 1-0.448 1-1 0-0.216-0.069-0.416-0.185-0.578L4.68 14.51C4.248 13.77 4 12.91 4 11.993c0-2.759 2.238-4.995 5-4.995h5.595l-1.297 1.297-0.078 0.087c-0.31 0.392-0.285 0.964 0.078 1.326 0.39 0.39 1.024 0.39 1.414 0l3.006-3.003 0.077-0.087c0.311-0.392 0.285-0.964-0.078-1.326l-3.005-3.003zm6.075 5.771C20.602 7.827 20.319 7.678 20 7.678c-0.552 0-1 0.448-1 1 0 0.208 0.064 0.4 0.172 0.56 0.523 0.79 0.828 1.737 0.828 2.755 0 2.76-2.238 4.996-5 4.996H9.416l1.294-1.292 0.083-0.095c0.281-0.361 0.28-0.871-0.006-1.23l-0.077-0.088-0.095-0.084c-0.362-0.28-0.873-0.278-1.232 0.006l-0.088 0.078-3.005 3.003-0.083 0.095c-0.281 0.361-0.28 0.872 0.006 1.231L6.289 18.7l3.005 3.003 0.095 0.084c0.392 0.304 0.96 0.277 1.32-0.084 0.362-0.362 0.388-0.933 0.077-1.326L10.71 20.29l-1.304-1.303h5.596l0.24-0.003C18.996 18.857 22 15.776 22 11.994c0-1.46-0.448-2.816-1.213-3.937V8.06z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
<path android:pathData="M8.75 3.75C8.75 2.231 7.519 1 6 1S3.25 2.231 3.25 3.75 4.481 6.5 6 6.5s2.75-1.231 2.75-2.75zm-4.5 0C4.25 2.784 5.034 2 6 2s1.75 0.784 1.75 1.75S6.966 5.5 6 5.5 4.25 4.716 4.25 3.75zM2.5 7.5h4.183c-0.164 0.31-0.286 0.646-0.358 1H2.5C2.224 8.5 2 8.724 2 9v0.5c0 1.26 1.099 2.614 3.096 2.93-0.322 0.22-0.59 0.513-0.781 0.854C2.205 12.713 1 11.087 1 9.5V9c0-0.828 0.672-1.5 1.5-1.5zm5.379 0c0.504-0.61 1.267-1 2.121-1 0.854 0 1.617 0.39 2.121 1 0.24 0.29 0.42 0.629 0.525 1 0.068 0.238 0.104 0.49 0.104 0.75 0 1.07-0.611 1.997-1.503 2.452-0.355 0.18-0.754 0.287-1.177 0.297L10 12H9.93c-0.423-0.011-0.822-0.117-1.177-0.298C7.861 11.247 7.25 10.32 7.25 9.25c0-0.26 0.036-0.512 0.104-0.75 0.104-0.371 0.285-0.71 0.525-1zm0.54 1C8.31 8.727 8.25 8.982 8.25 9.25c0 0.714 0.428 1.328 1.04 1.6C9.509 10.947 9.749 11 10 11c0.252 0 0.492-0.053 0.71-0.15 0.612-0.272 1.04-0.886 1.04-1.6 0-0.268-0.06-0.523-0.168-0.75-0.246-0.516-0.737-0.894-1.322-0.98C10.175 7.506 10.088 7.5 10 7.5c-0.088 0-0.175 0.006-0.26 0.02C9.155 7.605 8.664 7.983 8.418 8.5zm7.266 4.784c-0.19-0.341-0.459-0.634-0.781-0.853C16.9 12.114 18 10.759 18 9.5V9c0-0.276-0.224-0.5-0.5-0.5h-3.825c-0.072-0.354-0.194-0.69-0.357-1H17.5C18.328 7.5 19 8.172 19 9v0.5c0 1.587-1.206 3.212-3.315 3.784zm-1.198 0.087C14.223 13.14 13.878 13 13.5 13h-7c-0.432 0-0.821 0.183-1.095 0.475C5.154 13.743 5 14.104 5 14.5V15c0 1.971 1.86 4 5 4 3.14 0 5-2.029 5-4v-0.5c0-0.45-0.198-0.854-0.513-1.13zM6 14.5C6 14.224 6.224 14 6.5 14h7c0.276 0 0.5 0.224 0.5 0.5V15c0 1.438-1.432 3-4 3s-4-1.562-4-3v-0.5zM14 1c1.519 0 2.75 1.231 2.75 2.75S15.519 6.5 14 6.5s-2.75-1.231-2.75-2.75S12.481 1 14 1zm0 1c-0.966 0-1.75 0.784-1.75 1.75S13.034 5.5 14 5.5s1.75-0.784 1.75-1.75S14.966 2 14 2z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,3 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24">
<path android:pathData="M9.75 2c0.301 0 0.573 0.18 0.69 0.457l6.972 16.431C16.951 18.345 16.267 18 15.5 18c-0.031 0-0.063 0-0.094 0.002L13.92 14.5H5.58l-2.14 5.043c-0.161 0.381-0.601 0.56-0.983 0.397-0.381-0.161-0.559-0.602-0.397-0.983l7-16.5C9.177 2.18 9.45 2 9.75 2zm3.534 11L9.75 4.67 6.216 13h7.068zM12 20.5c0 0.828-0.672 1.5-1.5 1.5S9 21.328 9 20.5 9.672 19 10.5 19s1.5 0.672 1.5 1.5zm3.5 1.5c0.828 0 1.5-0.672 1.5-1.5S16.328 19 15.5 19 14 19.672 14 20.5s0.672 1.5 1.5 1.5zm5 0c0.828 0 1.5-0.672 1.5-1.5S21.328 19 20.5 19 19 19.672 19 20.5s0.672 1.5 1.5 1.5z" android:fillColor="@color/fluent_default_icon_tint"/>
</vector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="16dp" android:height="16dp" android:viewportWidth="16" android:viewportHeight="16">
<group android:translateX="-2" android:translateY="-1">
<path android:pathData="M10 2c1.657 0 3 1.343 3 3v1h1c1.105 0 2 0.895 2 2v7c0 1.105-0.895 2-2 2H6c-1.105 0-2-0.895-2-2V8c0-1.105 0.895-2 2-2h1V5c0-1.657 1.343-3 3-3zm0 8.5c-0.552 0-1 0.448-1 1s0.448 1 1 1 1-0.448 1-1-0.448-1-1-1zM10 4C9.448 4 9 4.448 9 5v1h2V5c0-0.552-0.448-1-1-1z" android:fillColor="@color/fluent_default_icon_tint"/>
</group>
</vector>

View File

@@ -9,26 +9,29 @@
<ImageView
android:id="@+id/more"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginTop="-6dp"
android:layout_marginRight="-8dp"
android:background="?android:selectableItemBackgroundBorderless"
android:scaleType="center"
android:tint="?android:textColorSecondary"
android:contentDescription="@string/more_options"
android:src="@drawable/ic_post_more" />
android:scaleType="center"
android:src="@drawable/ic_post_more"
android:tint="?android:textColorSecondary" />
<ImageView
android:id="@+id/visibility"
android:layout_width="24dp"
android:layout_height="20dp"
android:layout_alignParentEnd="true"
android:layout_below="@id/more"
android:layout_width="36dp"
android:layout_height="36dp"
android:layout_marginTop="-6dp"
android:layout_marginRight="6dp"
android:layout_toLeftOf="@id/more"
android:background="?android:selectableItemBackgroundBorderless"
android:scaleType="center"
android:tint="?android:textColorSecondary"
android:src="@drawable/ic_visibility" />
android:src="@drawable/ic_visibility"
android:tint="?android:textColorSecondary" />
<ImageView
android:id="@+id/avatar"
@@ -42,9 +45,9 @@
android:id="@+id/name_wrap"
android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_toEndOf="@id/avatar"
android:layout_toStartOf="@id/more"
android:layout_marginEnd="8dp">
android:layout_marginEnd="8dp"
android:layout_toStartOf="@id/visibility"
android:layout_toEndOf="@id/avatar">
<TextView
android:id="@+id/name"
@@ -52,8 +55,8 @@
android:layout_height="24dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:textAlignment="viewStart"
android:textAppearance="@style/m3_title_medium"
tools:text="Eugen" />
<TextView
@@ -62,10 +65,10 @@
android:layout_height="24dp"
android:layout_marginStart="8dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/m3_title_medium"
android:fontFamily="sans-serif"
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@style/m3_title_medium"
tools:text="boosted your cat picture" />
</org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout>
@@ -74,8 +77,9 @@
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@id/name_wrap"
android:layout_toEndOf="@id/avatar"
android:layout_marginEnd="8dp"
android:layout_toStartOf="@id/visibility"
android:layout_toEndOf="@id/avatar"
android:layoutDirection="locale"
android:orientation="horizontal">
@@ -94,6 +98,7 @@
android:layout_height="20dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:importantForAccessibility="no"
android:text="·"
android:textAppearance="@style/m3_title_small" />
@@ -101,8 +106,8 @@
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="20dp"
android:textAppearance="@style/m3_title_small"
android:singleLine="true"
android:textAppearance="@style/m3_title_small"
tools:text="3h" />
</org.joinmastodon.android.ui.views.HeaderSubtitleLinearLayout>

View File

@@ -2,15 +2,16 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="-6dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp">
android:layout_marginBottom="-12dp">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:paddingBottom="6dp"
android:background="?android:selectableItemBackground"
android:textAppearance="@style/m3_title_small"
android:drawableStart="@drawable/ic_fluent_arrow_repeat_all_20_filled"
android:drawableTint="?android:textColorSecondary"

View File

@@ -40,6 +40,7 @@
android:layout_marginTop="16dp"
android:textAppearance="@style/m3_title_small"
android:drawableStart="@drawable/ic_fluent_arrow_reply_20_filled"
tools:drawableEnd="@drawable/ic_fluent_earth_20_regular"
android:drawableTint="?android:textColorSecondary"
android:drawablePadding="6dp"
android:singleLine="true"

View File

@@ -28,10 +28,10 @@
<org.joinmastodon.android.ui.views.CoverImageView
android:id="@+id/cover"
android:layout_width="match_parent"
android:layout_height="229dp"
android:background="#808080"
android:layout_height="200dp"
android:background="?profileHeaderBackground"
android:contentDescription="@string/profile_header"
android:scaleType="centerCrop"/>
android:scaleType="centerCrop" />
<TextView
android:id="@+id/follows_you"
@@ -54,8 +54,8 @@
<FrameLayout
android:id="@+id/avatar_border"
android:layout_width="102dp"
android:layout_height="102dp"
android:layout_width="112dp"
android:layout_height="112dp"
android:layout_below="@id/cover"
android:layout_alignParentStart="true"
android:layout_marginTop="-40dp"
@@ -65,8 +65,8 @@
<ImageView
android:id="@+id/avatar"
android:layout_width="98dp"
android:layout_height="98dp"
android:layout_width="108dp"
android:layout_height="108dp"
android:layout_gravity="center"
android:scaleType="centerCrop"
android:contentDescription="@string/profile_picture"
@@ -234,22 +234,27 @@
android:layout_below="@id/avatar_border"
android:layout_alignParentStart="true"
android:layout_marginStart="16dp"
android:layout_marginTop="12dp"
android:layout_marginTop="17dp"
android:layout_marginBottom="0.4dp"
android:layout_toStartOf="@id/profile_action_btn_wrap"
android:textAppearance="@style/m3_headline_small"
android:textAlignment="viewStart"
android:textAppearance="@style/m3_headline_small"
tools:text="Eugen" />
<TextView
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_below="@id/name"
android:layout_marginStart="16dp"
android:layout_toStartOf="@id/profile_action_btn_wrap"
android:paddingHorizontal="16dp"
android:paddingTop="2dp"
android:paddingBottom="4dp"
android:background="?android:selectableItemBackground"
android:textAppearance="@style/m3_title_medium"
android:textColor="?android:textColorSecondary"
tools:text="\@Gargron"/>
tools:text="\@Gargron" />
<org.joinmastodon.android.ui.views.LinkedTextView
android:id="@+id/bio"
@@ -257,7 +262,7 @@
android:layout_height="wrap_content"
android:layout_below="@id/username"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginTop="4dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/m3_body_large"
android:textSize="16sp"

View File

@@ -367,5 +367,8 @@
<string name="install_update">Instal·lar</string>
<string name="privacy_policy_title">Mastodon i la teva privacitat</string>
<string name="privacy_policy_subtitle">Tot i que l\'aplicació Mastodon no recull cap dada, el servidor mitjançant el qual et registres pot tenir una política diferent. Pren un minut per revisar i acceptar la política de privadesa de l\'aplicació Mastodon i la política de privadesa del teu servidor.</string>
<string name="i_agree">Hi estic d\'acord</string>
<string name="i_agree">D\'acord</string>
<!-- Missing strings -->
<string name="bookmarks">Marcadors</string>
<string name="pinned_posts">Fixat</string>
</resources>

View File

@@ -414,4 +414,6 @@
<string name="privacy_policy_subtitle">Obwohl die Mastodon-App keine Daten sammelt, kann der Server, über den Sie sich anmelden, eine andere Richtlinie haben. Nehmen Sie sich eine Minute Zeit, um die Mastodon-Datenschutzrichtlinien und die Datenschutzrichtlinien Ihres Servers zu lesen und zu akzeptieren.</string>
<string name="i_agree">Ich stimme zu</string>
<string name="settings_always_reveal_content_warnings">Inhaltswarnungen immer ausklappen</string>
<string name="disable_marquee">Laufschrift in Titelleisten deaktivieren</string>
<string name="copied_to_clipboard">In die Zwischenablage kopiert</string>
</resources>

View File

@@ -38,6 +38,7 @@
</plurals>
<string name="posts">게시물</string>
<string name="posts_and_replies">게시물과 답장</string>
<string name="pinned_posts">고정됨</string>
<string name="media">미디어</string>
<string name="profile_about">정보</string>
<string name="button_follow">팔로우</string>
@@ -108,9 +109,20 @@
<string name="action_vote">투표</string>
<string name="tap_to_reveal">눌러서 확인</string>
<string name="delete">삭제</string>
<string name="delete_and_redraft">삭제하고 다시 쓰기</string>
<string name="confirm_delete_title">게시물 삭제</string>
<string name="confirm_delete_and_redraft_title">게시물 삭제하고 다시 쓰기</string>
<string name="confirm_delete">정말로 이 게시물을 삭제하시겠습니까?</string>
<string name="confirm_delete_and_redraft">정말로 이 게시물을 삭제하고 다시 쓰시겠습니까?</string>
<string name="deleting">삭제 중…</string>
<string name="pin_post">고정</string>
<string name="confirm_pin_post_title">게시물 고정</string>
<string name="confirm_pin_post">정말로 이 게시물을 고정하시겠습니까?</string>
<string name="pinning">고정 중…</string>
<string name="unpin_post">고정 해제</string>
<string name="confirm_unpin_post_title">게시물 고정 해제</string>
<string name="confirm_unpin_post">정말로 이 게시물을 고정 해제하시겠습니까?</string>
<string name="unpinning">고정 해제 중…</string>
<string name="notification_channel_audio_player">오디오 재생</string>
<string name="play">재생</string>
<string name="pause">일시정지</string>
@@ -189,6 +201,7 @@
<string name="compose_hint">무슨 생각을 하고 있는지 입력하거나 붙여넣으세요</string>
<string name="content_warning">열람 주의</string>
<string name="add_image_description">이미지 설명 추가…</string>
<string name="image_description">이미지 설명</string>
<string name="retry_upload">업로드 재시도</string>
<string name="edit_image">이미지 편집</string>
<string name="save">저장</string>
@@ -196,6 +209,7 @@
<string name="alt_text_subtitle">대체 텍스트는 저시력자나 시각장애인들에게 당신의 사진을 설명합니다. 문맥을 파악할 수 있는 설명들만 넣도록 하세요.</string>
<string name="alt_text_hint">예시: 강아지가 의심스러운 가는 눈초리로 카메라를 쳐다보고 있습니다.</string>
<string name="visibility_public">공개</string>
<string name="visibility_unlisted">타임라인에 비표시</string>
<string name="visibility_followers_only">팔로워 전용</string>
<string name="visibility_private">멘션한 사람만</string>
<string name="search_all">모두</string>
@@ -221,8 +235,12 @@
<string name="theme_dark">어두움</string>
<string name="theme_true_black">진정한 검정 모드</string>
<string name="settings_behavior">동작</string>
<string name="settings_show_replies">답장 표시</string>
<string name="settings_show_boosts">리블로그 표시</string>
<string name="settings_load_new_posts">자동으로 새 포스트 불러오기</string>
<string name="settings_gif">아바타와 에모지의 애니메이션을 재생</string>
<string name="settings_custom_tabs">앱내 브라우저 사용</string>
<string name="settings_show_interaction_counts">상호 작용 수 표시</string>
<string name="settings_notifications">알림</string>
<string name="notify_me_when">알림을 보낼 조건</string>
<string name="notify_anyone">누구든</string>
@@ -255,8 +273,11 @@
<string name="button_reblog">리블로그</string>
<string name="button_favorite">좋아요</string>
<string name="button_share">공유</string>
<string name="button_bookmark">보관</string>
<string name="bookmarks">보관함</string>
<string name="media_no_description">설명이 없는 미디어</string>
<string name="add_media">미디어 추가</string>
<string name="mark_media_as_sensitive">미디어를 민감함으로 설정하기</string>
<string name="add_poll">투표 추가</string>
<string name="emoji">에모지</string>
<string name="post_visibility">게시물 공개범위</string>
@@ -269,6 +290,8 @@
<string name="open_in_browser">브라우저에서 열기</string>
<string name="hide_boosts_from_user">%s의 리블로그를 숨기기</string>
<string name="show_boosts_from_user">%s의 리블로그를 보이기</string>
<string name="user_post_notifications_on">%s의 게시물 알림 켜기</string>
<string name="user_post_notifications_off">%s의 게시물 알림 끄기</string>
<string name="signup_reason">가입하려는 이유가 무엇인가요?</string>
<string name="signup_reason_note">이 정보는 우리가 심사를 하는 데에 참고할 수 있습니다.</string>
<string name="clear">모두 지우기</string>
@@ -283,11 +306,13 @@
<string name="file_saved">파일 저장됨</string>
<string name="downloading">다운로드중…</string>
<string name="no_app_to_handle_action">이 동작을 처리할 앱이 없습니다</string>
<string name="local_timeline">커뮤니티</string>
<string name="local_timeline">로컬</string>
<string name="federated_timeline">연합</string>
<string name="trending_posts_info_banner">당신이 속한 마스토돈 서버에서 관심을 끌고 있는 게시물들입니다.</string>
<string name="trending_hashtags_info_banner">당신이 속한 마스토돈 서버에서 관심을 끌고 있는 해시태그들입니다.</string>
<string name="trending_links_info_banner">당신이 속한 마스토돈 서버에서 가장 많이 공유되고 있는 소식들입니다.</string>
<string name="local_timeline_info_banner">당신과 같은 마스토돈 서버에 존재하는 사람들이 공유한 최신 게시물들입니다.</string>
<string name="federated_timeline_info_banner">당신이 속한 연합에 존재하는 사람들이 공유한 최신 게시물들입니다.</string>
<string name="dismiss">지우기</string>
<string name="see_new_posts">새 게시물 보기</string>
<string name="load_missing_posts">빈 게시물 불러오기</string>
@@ -356,6 +381,18 @@
<!-- %s is file size -->
<string name="download_update">다운로드 (%s)</string>
<string name="install_update">설치</string>
<string name="check_for_update">업데이트 확인</string>
<string name="no_update_available">사용 가능한 업데이트 없음</string>
<string name="privacy_policy_title">마스토돈 및 개인정보</string>
<string name="i_agree">동의합니다</string>
<string name="list_timelines">리스트</string>
<string name="favorited_posts">좋아요</string>
<string name="follow_requests">팔로우 요청</string>
<string name="accept_follow_request">팔로우 요청 허가</string>
<string name="reject_follow_request">팔로우 요청 거부</string>
<string name="lists_with_user">%s 님이 포함된 리스트</string>
<string name="empty_list">리스트에 아무 것도 없습니다</string>
<string name="instance_signup_closed">이 서버는 가입이 막혀 있는 상태입니다.</string>
<string name="settings_always_reveal_content_warnings">열람주의 툿을 항상 펼치기</string>
<string name="disable_marquee">제목 표시줄의 텍스트 스크롤 비활성화</string>
</resources>

View File

@@ -4,6 +4,7 @@
<attr name="colorSecondary" format="color"/>
<attr name="colorBackgroundLight" format="color"/>
<attr name="colorBackgroundLightest" format="color"/>
<attr name="colorBackgroundPopup" format="color"/>
<attr name="colorDarkIcon" format="color"/>
<attr name="colorPollMostVoted" format="color"/>
<attr name="colorPollVoted" format="color"/>
@@ -15,6 +16,7 @@
<attr name="colorSearchHint" format="color"/>
<attr name="colorTabInactive" format="color"/>
<attr name="colorAccentLightest" format="color"/>
<attr name="profileHeaderBackground" format="color"/>
<attr name="primaryLargeButtonStyle" format="reference"/>
<attr name="secondaryLargeButtonStyle" format="reference"/>

View File

@@ -18,4 +18,5 @@
<item name="notifications_all" type="id"/>
<item name="notifications_mentions" type="id"/>
<item name="notifications_posts" type="id"/>
</resources>

View File

@@ -421,5 +421,8 @@
<string name="reject_follow_request">Reject follow request</string>
<string name="lists_with_user">Lists with %s</string>
<string name="empty_list">This list is empty</string>
<string name="instance_signup_closed">This server does not accept new registrations.</string>
<string name="settings_always_reveal_content_warnings">Always reveal content warnings</string>
<string name="disable_marquee">Disable scrolling text in title bars</string>
<string name="copied_to_clipboard">Copied to clipboard</string>
</resources>

View File

@@ -22,6 +22,7 @@
<item name="colorSecondary">#E9EDF2</item>
<item name="colorBackgroundLight">@color/gray_50</item>
<item name="colorBackgroundLightest">@color/gray_25</item>
<item name="colorBackgroundPopup">?colorBackgroundLightest</item>
<item name="colorDarkIcon">@color/gray_900</item>
<item name="colorWindowBackground">@color/white</item>
<item name="android:statusBarColor">@color/gray_50</item>
@@ -35,6 +36,7 @@
<item name="colorSearchHint">@color/gray_600</item>
<item name="colorTabInactive">@color/gray_400</item>
<item name="colorAccentLightest">@color/primary_100</item>
<item name="profileHeaderBackground">@color/gray_500</item>
<item name="buttonBackground">@drawable/bg_button_primary_dark_on_light</item>
<item name="android:editTextBackground">@drawable/bg_edittext_light</item>
@@ -67,6 +69,7 @@
<item name="colorSecondary">#E9EDF2</item>
<item name="colorBackgroundLight">@color/gray_700</item>
<item name="colorBackgroundLightest">@color/gray_900</item>
<item name="colorBackgroundPopup">?colorBackgroundLightest</item>
<item name="colorDarkIcon">@color/gray_25</item>
<item name="colorWindowBackground">@color/gray_800</item>
<item name="android:statusBarColor">@color/gray_800</item>
@@ -78,6 +81,7 @@
<item name="colorAccentLight">@color/primary_600</item>
<item name="colorAccentLightest">@color/primary_800</item>
<item name="colorTabInactive">@color/gray_400</item>
<item name="profileHeaderBackground">?colorWindowBackground</item>
<!-- TODO dark colors -->
<item name="colorSearchField">@color/gray_700</item>
@@ -93,7 +97,17 @@
</style>
<style name="Theme.Mastodon.Dark.TrueBlack">
<item name="colorWindowBackground">#000</item>
<item name="android:navigationBarColor">@color/black</item>
<item name="android:colorBackground">@color/black</item>
<item name="android:statusBarColor">@color/black</item>
<item name="android:actionBarTheme">@style/Theme.Mastodon.Toolbar.Dark.TrueBlack</item>
<item name="colorBackgroundLight">@color/black</item>
<item name="colorWindowBackground">@color/black</item>
<item name="colorButtonText">@color/black</item>
<item name="colorPollVoted">@color/gray_800</item>
<item name="colorSearchField">@color/gray_900</item>
<item name="colorBackgroundLightest">@color/black</item>
<item name="colorBackgroundPopup">@color/gray_900</item>
</style>
<style name="Theme.Mastodon.AutoLightDark" parent="Theme.Mastodon.Light"/>
@@ -111,6 +125,10 @@
<item name="android:textColorSecondary">@color/gray_50</item>
</style>
<style name="Theme.Mastodon.Toolbar.Dark.TrueBlack" parent="android:ThemeOverlay.Material.Dark.ActionBar">
<item name="android:colorPrimary">@color/black</item>
</style>
<style name="Theme.Mastodon.Toolbar.Profile">
<item name="android:textColorPrimary">@color/gray_50</item>
<item name="android:textColorSecondary">@color/gray_50</item>

View File

@@ -1,43 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en" />
<locale android:name="ar" />
<locale android:name="bn-BD"/>
<locale android:name="bs" />
<locale android:name="ca" />
<locale android:name="cs" />
<locale android:name="de" />
<locale android:name="gd-GB"/>
<locale android:name="el" />
<locale android:name="es" />
<locale android:name="eu" />
<locale android:name="fi" />
<locale android:name="fr" />
<loacle android:name="sl"/>
<locale android:name="gl" />
<locale android:name="hi-IN"/>
<locale android:name="hr" />
<locale android:name="hy" />
<locale android:name="id"/>
<locale android:name="it" />
<locale android:name="iw" />
<locale android:name="ja" />
<locale android:name="kab" />
<locale android:name="ko" />
<locale android:name="nl"/>
<locale android:name="oc" />
<locale android:name="pl" />
<locale android:name="pt-BR" />
<locale android:name="pt-PT" />
<locale android:name="ro"/>
<locale android:name="ru" />
<locale android:name="si-LK"/>
<locale android:name="sl"/>
<locale android:name="sv" />
<locale android:name="th" />
<locale android:name="tr" />
<locale android:name="uk" />
<locale android:name="vi" />
<locale android:name="zh-Hans" />
<locale android:name="zh-Hant" />
<locale android:name="ar-SA"/>
<locale android:name="bn-BD"/>
<locale android:name="bs-BA"/>
<locale android:name="ca-ES"/>
<locale android:name="cs-CZ"/>
<locale android:name="de-DE"/>
<locale android:name="el-GR"/>
<locale android:name="en"/>
<locale android:name="es-ES"/>
<locale android:name="eu-ES"/>
<locale android:name="fi-FI"/>
<locale android:name="fr-FR"/>
<locale android:name="gd-GB"/>
<locale android:name="gl-ES"/>
<locale android:name="hi-IN"/>
<locale android:name="hr-HR"/>
<locale android:name="hy-AM"/>
<locale android:name="in-ID"/>
<locale android:name="it-IT"/>
<locale android:name="iw-IL"/>
<locale android:name="ja-JP"/>
<locale android:name="kab"/>
<locale android:name="ko-KR"/>
<locale android:name="nl-NL"/>
<locale android:name="oc-FR"/>
<locale android:name="pl-PL"/>
<locale android:name="pt-BR"/>
<locale android:name="pt-PT"/>
<locale android:name="ru-RU"/>
<locale android:name="si-LK"/>
<locale android:name="sv-SE"/>
<locale android:name="th-TH"/>
<locale android:name="tr-TR"/>
<locale android:name="uk-UA"/>
<locale android:name="vi-VN"/>
<locale android:name="zh-CN"/>
<locale android:name="zh-TW"/>
</locale-config>

View File

@@ -0,0 +1,44 @@
// Run: java tools/GenerateLocaleConfig.java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
public class GenerateLocaleConfig{
public static void main(String[] args) throws IOException{
File dir=new File("../mastodon/src/main/res/");
if(!dir.exists())
dir=new File("mastodon/src/main/res");
if(!dir.exists())
throw new RuntimeException("Please run from project directory (can't find mastodon/src/main/res)");
ArrayList<String> locales=new ArrayList<>();
locales.add("en");
for(File file:dir.listFiles()){
String name=file.getName();
if(file.isDirectory() && name.startsWith("values-")){
if(new File(file, "strings.xml").exists()){
locales.add(name.substring(name.indexOf('-')+1).replace("-r", "-"));
}
}
}
locales.sort(String::compareTo);
try(OutputStreamWriter writer=new OutputStreamWriter(new FileOutputStream(new File(dir, "xml/locales_config.xml")), StandardCharsets.UTF_8)){
writer.write("""
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
""");
for(String locale : locales){
writer.write("\t<locale android:name=\"");
writer.write(locale);
writer.write("\"/>\n");
}
writer.write("</locale-config>");
}
}
}