Compare commits
19 Commits
v1.1.4+for
...
v1.1.4+for
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef207f885b | ||
|
|
c4eee28335 | ||
|
|
6fe466779e | ||
|
|
e71db1b883 | ||
|
|
b6efafe99d | ||
|
|
688d466f8e | ||
|
|
3c5797932e | ||
|
|
48a5e262ce | ||
|
|
63b0365208 | ||
|
|
972c05d60b | ||
|
|
acb5778e0b | ||
|
|
7694c50358 | ||
|
|
7ffa368d10 | ||
|
|
93d57d847e | ||
|
|
83a4f5eec2 | ||
|
|
836c2dba8d | ||
|
|
13ae8d2ebe | ||
|
|
98dafb4e49 | ||
|
|
85b8bae42e |
34
README.md
34
README.md
@@ -1,34 +1,38 @@
|
||||

|
||||
|
||||
# Mastodon for Android Fork
|
||||
# Mastodos
|
||||
|
||||
> A fork of the [official Mastodon Android app](https://github.com/mastodon/mastodon-android) adding important features that are missing in the official app and possibly won’t ever be implemented, such as the federated timeline, unlisted posting, bookmarks and an image description viewer.
|
||||
|
||||
[](https://github.com/sk22/mastodon-android-fork/releases/latest/download/mastodos.apk)
|
||||
|
||||
## Changes
|
||||
|
||||
* [Enable "Unlisted" as a visibility option](https://github.com/sk22/mastodon-android-fork/tree/feature/enable-unlisted)
|
||||
([Pull request](https://github.com/mastodon/mastodon-android/pull/103)) and
|
||||
[set as default](https://github.com/sk22/mastodon-android-fork/tree/feature/enable-unlisted-as-default)
|
||||
* [Add "Federation" tab and change Discover tab order](https://github.com/sk22/mastodon-android-fork/tree/feature/add-federated-timeline) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/8))
|
||||
### Features
|
||||
|
||||
* [Add “Unlisted” as a post visibility option](https://github.com/sk22/mastodon-android-fork/tree/feature/enable-unlisted)
|
||||
([Pull request](https://github.com/mastodon/mastodon-android/pull/103))
|
||||
* [Add “Federation” tab and change Discover tab order](https://github.com/sk22/mastodon-android-fork/tree/feature/add-federated-timeline) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/8))
|
||||
* [Add image description button and viewer](https://github.com/sk22/mastodon-android-fork/tree/feature/display-alt-text) ([Pull request](https://github.com/mastodon/mastodon-android/pull/129))
|
||||
* [Implement pinning posts and displaying pinned posts](https://github.com/sk22/mastodon-android-fork/tree/feature/pin-posts) ([Pull request](https://github.com/mastodon/mastodon-android/pull/140))
|
||||
* [Display full image when adding image description](https://github.com/sk22/mastodon-android-fork/tree/feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
|
||||
* [Always preserve content warnings when replying](https://github.com/sk22/mastodon-android-fork/tree/feature/always-preserve-cw) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/113))
|
||||
* [Make back button return to the home tab before exiting the app](https://github.com/sk22/mastodon-android-fork/tree/feature/back-returns-home) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/118))
|
||||
* [Implement a bookmark button and list](https://github.com/sk22/mastodon-android-fork/tree/feature/bookmarks) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/22))
|
||||
|
||||
### Behavior
|
||||
|
||||
* [Make back button return to the home tab before exiting the app](https://github.com/sk22/mastodon-android-fork/tree/feature/back-returns-home) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/118))
|
||||
* [Always preserve content warnings when replying](https://github.com/sk22/mastodon-android-fork/tree/feature/always-preserve-cw) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/113))
|
||||
* [Display full image when adding image description](https://github.com/sk22/mastodon-android-fork/tree/feature/compose-image-description-full-image) ([Pull request](https://github.com/mastodon/mastodon-android/pull/182))
|
||||
* [Implement deleting and re-drafting](https://github.com/sk22/mastodon-android-fork/tree/feature/delete-redraft) ([Fixes issue](https://github.com/mastodon/mastodon-android/issues/21))
|
||||
|
||||
## Fork-specific changes
|
||||
### Branding
|
||||
|
||||
* Custom app name
|
||||
* App name “Mastodos”
|
||||
* Pink primary color
|
||||
* Custom icon: Modulate upstream icon using ImageMagick
|
||||
|
||||
```bash
|
||||
mogrify -modulate 90,100,140 mastodon/src/main/res/mipmap-*/ic_launcher*.png
|
||||
```
|
||||
|
||||
* Custom primary color: Hue of all `primary` colors in `colors.xml` is rotated, on basis of upstream Mastodon's [old branding](https://github.com/mastodon/mastodon-android/commit/74f03026cfcfcfd23237c38ff47d2b2a98a6f92a#diff-59134ec2a1cf3761f80b0ecccbbf8b9e433d9780d2f5c5d6ac3ac8cc254e808f)
|
||||
by `109.8°` (equivalent of `161%`, done by hand using
|
||||
[PineTools](https://pinetools.com/shift-hue-color))
|
||||
|
||||
## Building
|
||||
|
||||
As this app is using Java 17 features, you need JDK 17 or newer to build it. Other than that, everything is pretty standard. You can either import the project into Android Studio and build it from there, or run the following command in the project directory:
|
||||
|
||||
@@ -9,8 +9,8 @@ android {
|
||||
applicationId "org.joinmastodon.android.sk"
|
||||
minSdk 23
|
||||
targetSdk 33
|
||||
versionCode 25
|
||||
versionName "1.1.4+fork.25"
|
||||
versionCode 28
|
||||
versionName "1.1.4+fork.28"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.joinmastodon.android.api.MastodonAPIController;
|
||||
import org.joinmastodon.android.events.SelfUpdateStateChangedEvent;
|
||||
|
||||
import java.io.File;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -36,7 +38,7 @@ import okhttp3.Response;
|
||||
|
||||
@Keep
|
||||
public class GithubSelfUpdaterImpl extends GithubSelfUpdater{
|
||||
private static final long CHECK_PERIOD=24*3600*1000L;
|
||||
private static final long CHECK_PERIOD=6*3600*1000L;
|
||||
private static final String TAG="GithubSelfUpdater";
|
||||
|
||||
private UpdateState state=UpdateState.NO_UPDATE;
|
||||
@@ -101,6 +103,12 @@ public class GithubSelfUpdaterImpl extends GithubSelfUpdater{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkForUpdates() {
|
||||
setState(UpdateState.CHECKING);
|
||||
MastodonAPIController.runInBackground(this::actuallyCheckForUpdates);
|
||||
}
|
||||
|
||||
private void actuallyCheckForUpdates(){
|
||||
Request req=new Request.Builder()
|
||||
.url("https://api.github.com/repos/sk22/mastodon-android-fork/releases/latest")
|
||||
|
||||
@@ -185,7 +185,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
private ImageView sendError;
|
||||
private View sendingOverlay;
|
||||
private WindowManager wm;
|
||||
private StatusPrivacy statusVisibility=StatusPrivacy.UNLISTED;
|
||||
private StatusPrivacy statusVisibility=StatusPrivacy.PUBLIC;
|
||||
private ComposeAutocompleteSpan currentAutocompleteSpan;
|
||||
private FrameLayout mainEditTextWrap;
|
||||
private ComposeAutocompleteViewController autocompleteViewController;
|
||||
@@ -362,6 +362,7 @@ public class ComposeFragment extends MastodonToolbarFragment implements OnBackPr
|
||||
spoilerEdit.setVisibility(View.VISIBLE);
|
||||
spoilerBtn.setSelected(true);
|
||||
}else if(editingStatus!=null && !TextUtils.isEmpty(editingStatus.spoilerText)){
|
||||
hasSpoiler=true;
|
||||
spoilerEdit.setVisibility(View.VISIBLE);
|
||||
spoilerEdit.setText(getArguments().getString("sourceSpoiler", editingStatus.spoilerText));
|
||||
spoilerBtn.setSelected(true);
|
||||
|
||||
@@ -142,7 +142,6 @@ public class HomeTimelineFragment extends StatusListFragment{
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusCreated(StatusCreatedEvent ev){
|
||||
prependItems(Collections.singletonList(ev.status), true);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
@@ -71,6 +72,7 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
private PushSubscription pushSubscription;
|
||||
|
||||
private ImageView themeTransitionWindowView;
|
||||
private TextItem checkForUpdateItem;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState){
|
||||
@@ -118,6 +120,10 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
items.add(new TextItem(R.string.settings_privacy_policy, ()->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")));
|
||||
|
||||
items.add(new RedHeaderItem(R.string.settings_spicy));
|
||||
if (GithubSelfUpdater.needSelfUpdating()) {
|
||||
checkForUpdateItem = new TextItem(R.string.check_for_update, GithubSelfUpdater.getInstance()::checkForUpdates);
|
||||
items.add(checkForUpdateItem);
|
||||
}
|
||||
items.add(new TextItem(R.string.settings_clear_cache, this::clearImageCache));
|
||||
items.add(new TextItem(R.string.log_out, this::confirmLogOut));
|
||||
|
||||
@@ -326,11 +332,25 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
|
||||
@Subscribe
|
||||
public void onSelfUpdateStateChanged(SelfUpdateStateChangedEvent ev){
|
||||
if(items.get(0) instanceof UpdateItem item){
|
||||
RecyclerView.ViewHolder holder=list.findViewHolderForAdapterPosition(0);
|
||||
if(holder instanceof UpdateViewHolder uvh){
|
||||
uvh.bind(item);
|
||||
}
|
||||
checkForUpdateItem.loading = ev.state == GithubSelfUpdater.UpdateState.CHECKING;
|
||||
if (list.findViewHolderForAdapterPosition(items.indexOf(checkForUpdateItem)) instanceof TextViewHolder tvh) tvh.rebind();
|
||||
|
||||
UpdateItem updateItem = null;
|
||||
if(items.get(0) instanceof UpdateItem item0) {
|
||||
updateItem = item0;
|
||||
} else if (ev.state != GithubSelfUpdater.UpdateState.CHECKING
|
||||
&& ev.state != GithubSelfUpdater.UpdateState.NO_UPDATE) {
|
||||
updateItem = new UpdateItem();
|
||||
items.add(0, updateItem);
|
||||
list.setAdapter(new SettingsAdapter());
|
||||
}
|
||||
|
||||
if(updateItem != null && list.findViewHolderForAdapterPosition(0) instanceof UpdateViewHolder uvh){
|
||||
uvh.bind(updateItem);
|
||||
}
|
||||
|
||||
if (ev.state == GithubSelfUpdater.UpdateState.NO_UPDATE) {
|
||||
Toast.makeText(getActivity(), R.string.no_update_available, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,10 +418,16 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
private class TextItem extends Item{
|
||||
private String text;
|
||||
private Runnable onClick;
|
||||
private boolean loading;
|
||||
|
||||
public TextItem(@StringRes int text, Runnable onClick){
|
||||
public TextItem(@StringRes int text, Runnable onClick) {
|
||||
this(text, onClick, false);
|
||||
}
|
||||
|
||||
public TextItem(@StringRes int text, Runnable onClick, boolean loading){
|
||||
this.text=getString(text);
|
||||
this.onClick=onClick;
|
||||
this.loading=loading;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -630,14 +656,18 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
|
||||
private class TextViewHolder extends BindableViewHolder<TextItem> implements UsableRecyclerView.Clickable{
|
||||
private final TextView text;
|
||||
private final ProgressBar progress;
|
||||
|
||||
public TextViewHolder(){
|
||||
super(getActivity(), R.layout.item_settings_text, list);
|
||||
text=(TextView) itemView;
|
||||
text = itemView.findViewById(R.id.text);
|
||||
progress = itemView.findViewById(R.id.progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(TextItem item){
|
||||
text.setText(item.text);
|
||||
progress.animate().alpha(item.loading ? 1 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -692,8 +722,9 @@ public class SettingsFragment extends MastodonToolbarFragment{
|
||||
@Override
|
||||
public void onBind(UpdateItem item){
|
||||
GithubSelfUpdater updater=GithubSelfUpdater.getInstance();
|
||||
GithubSelfUpdater.UpdateInfo info=updater.getUpdateInfo();
|
||||
GithubSelfUpdater.UpdateState state=updater.getState();
|
||||
if (state == GithubSelfUpdater.UpdateState.CHECKING) return;
|
||||
GithubSelfUpdater.UpdateInfo info=updater.getUpdateInfo();
|
||||
if(state!=GithubSelfUpdater.UpdateState.DOWNLOADED){
|
||||
text.setText(getString(R.string.update_available, info.version));
|
||||
button.setText(getString(R.string.download_update, UiUtils.formatFileSize(getActivity(), info.size, false)));
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.joinmastodon.android.events.StatusCountersUpdatedEvent;
|
||||
import org.joinmastodon.android.events.StatusCreatedEvent;
|
||||
import org.joinmastodon.android.events.StatusDeletedEvent;
|
||||
import org.joinmastodon.android.events.StatusUpdatedEvent;
|
||||
import org.joinmastodon.android.events.StatusUnpinnedEvent;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.displayitems.ExtendedFooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
@@ -63,6 +62,59 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
|
||||
protected void onStatusCreated(StatusCreatedEvent ev){}
|
||||
|
||||
protected void onStatusUpdated(StatusUpdatedEvent ev){
|
||||
ArrayList<Status> statusesForDisplayItems=new ArrayList<>();
|
||||
for(int i=0;i<data.size();i++){
|
||||
Status s=data.get(i);
|
||||
if(s.reblog!=null && s.reblog.id.equals(ev.status.id)){
|
||||
s.reblog=ev.status;
|
||||
statusesForDisplayItems.add(s);
|
||||
}else if(s.id.equals(ev.status.id)){
|
||||
data.set(i, ev.status);
|
||||
statusesForDisplayItems.add(ev.status);
|
||||
}
|
||||
}
|
||||
for(int i=0;i<preloadedData.size();i++){
|
||||
Status s=preloadedData.get(i);
|
||||
if(s.reblog!=null && s.reblog.id.equals(ev.status.id)){
|
||||
s.reblog=ev.status;
|
||||
}else if(s.id.equals(ev.status.id)){
|
||||
preloadedData.set(i, ev.status);
|
||||
}
|
||||
}
|
||||
|
||||
if(statusesForDisplayItems.isEmpty())
|
||||
return;
|
||||
|
||||
for(Status s:statusesForDisplayItems){
|
||||
int i=0;
|
||||
for(StatusDisplayItem item:displayItems){
|
||||
if(item.parentID.equals(s.id)){
|
||||
int start=i;
|
||||
for(;i<displayItems.size();i++){
|
||||
if(!displayItems.get(i).parentID.equals(s.id))
|
||||
break;
|
||||
}
|
||||
List<StatusDisplayItem> postItems=displayItems.subList(start, i);
|
||||
postItems.clear();
|
||||
postItems.addAll(buildDisplayItems(s));
|
||||
int oldSize=i-start, newSize=postItems.size();
|
||||
if(oldSize==newSize){
|
||||
adapter.notifyItemRangeChanged(start, newSize);
|
||||
}else if(oldSize<newSize){
|
||||
adapter.notifyItemRangeChanged(start, oldSize);
|
||||
adapter.notifyItemRangeInserted(start+oldSize, newSize-oldSize);
|
||||
}else{
|
||||
adapter.notifyItemRangeChanged(start, newSize);
|
||||
adapter.notifyItemRangeRemoved(start+newSize, oldSize-newSize);
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Status getContentStatusByID(String id){
|
||||
Status s=getStatusByID(id);
|
||||
return s==null ? null : s.getContentStatus();
|
||||
@@ -138,6 +190,11 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
|
||||
StatusListFragment.this.onStatusCreated(ev);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusUpdated(StatusUpdatedEvent ev){
|
||||
StatusListFragment.this.onStatusUpdated(ev);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPollUpdated(PollUpdatedEvent ev){
|
||||
if(!ev.accountID.equals(accountID))
|
||||
|
||||
@@ -23,6 +23,8 @@ public abstract class GithubSelfUpdater{
|
||||
return BuildConfig.BUILD_TYPE.equals("githubRelease") || BuildConfig.BUILD_TYPE.equals("debug");
|
||||
}
|
||||
|
||||
public abstract void checkForUpdates();
|
||||
|
||||
public abstract void maybeCheckForUpdates();
|
||||
|
||||
public abstract GithubSelfUpdater.UpdateState getState();
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="daffdsa"/>
|
||||
android:layoutDirection="locale">
|
||||
<TextView
|
||||
android:id="@+id/text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="48dp"
|
||||
android:paddingRight="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textSize="16sp"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:singleLine="true"
|
||||
android:ellipsize="end"
|
||||
tools:text="Account settings"/>
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:alpha="0"
|
||||
/>
|
||||
</LinearLayout>
|
||||
@@ -271,7 +271,7 @@
|
||||
<string name="settings_privacy_policy">Datenschutzbestimmungen</string>
|
||||
<string name="settings_spicy">Gefährliches</string>
|
||||
<string name="settings_clear_cache">Medien-Cache leeren</string>
|
||||
<string name="settings_app_version">Mastodon für Android v%1$s (%2$d)</string>
|
||||
<string name="settings_app_version">Mastodos v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Medien-Cache geleert</string>
|
||||
<string name="confirm_log_out">Bist du dir sicher, dass du dich abmelden möchtest?</string>
|
||||
<string name="sensitive_content">Sensibler Inhalt</string>
|
||||
@@ -387,10 +387,12 @@
|
||||
<string name="upload_error_connection_lost">Dein Gerät hat gerade keinen Zugang zum Internet</string>
|
||||
<string name="upload_processing">wird verarbeitet …</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_available">Mastodon für Android %s kann nun heruntergeladen werden.</string>
|
||||
<string name="update_available">Mastodos %s kann nun heruntergeladen werden.</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_ready">Mastodon für Android %s wurde heruntergeladen und kann nun installiert werden.</string>
|
||||
<string name="update_ready">Mastodos %s wurde heruntergeladen und kann nun installiert werden.</string>
|
||||
<!-- %s is file size -->
|
||||
<string name="download_update">Download (%s)</string>
|
||||
<string name="install_update">Installieren</string>
|
||||
<string name="check_for_update">Auf Update prüfen</string>
|
||||
<string name="no_update_available">Kein Update verfügbar</string>
|
||||
</resources>
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
<string name="settings_privacy_policy">Privacy policy</string>
|
||||
<string name="settings_spicy">The spicy zone</string>
|
||||
<string name="settings_clear_cache">Clear media cache</string>
|
||||
<string name="settings_app_version">Mastodon for Android v%1$s (%2$d)</string>
|
||||
<string name="settings_app_version">Mastodos v%1$s (%2$d)</string>
|
||||
<string name="media_cache_cleared">Media cache cleared</string>
|
||||
<string name="confirm_log_out">Are you sure you want to sign out?</string>
|
||||
<string name="sensitive_content">Sensitive content</string>
|
||||
@@ -396,12 +396,14 @@
|
||||
<string name="upload_error_connection_lost">Your device lost connection to the internet</string>
|
||||
<string name="upload_processing">Processing…</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_available">Mastodon for Android %s is ready to download.</string>
|
||||
<string name="update_available">Mastodos %s is ready to download.</string>
|
||||
<!-- %s is version like 1.2.3 -->
|
||||
<string name="update_ready">Mastodon for Android %s is downloaded and ready to install.</string>
|
||||
<string name="update_ready">Mastodos %s is downloaded and ready to install.</string>
|
||||
<!-- %s is file size -->
|
||||
<string name="download_update">Download (%s)</string>
|
||||
<string name="install_update">Install</string>
|
||||
<string name="check_for_update">Check for update</string>
|
||||
<string name="no_update_available">No update available</string>
|
||||
<string name="privacy_policy_title">Mastodon and your privacy</string>
|
||||
<string name="privacy_policy_subtitle">Although the Mastodon app does not collect any data, the server you sign up through may have a different policy. Take a minute to review and agree to the Mastodon app privacy policy and your server\'s privacy policy.</string>
|
||||
<string name="i_agree">I Agree</string>
|
||||
|
||||
Reference in New Issue
Block a user