feat(settings): implement settings export
This commit is contained in:
parent
d87d656002
commit
09a7da2952
|
@ -3,6 +3,11 @@ package org.joinmastodon.android.fragments.settings;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
@ -11,9 +16,15 @@ import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
import com.google.gson.ToNumberPolicy;
|
||||||
|
|
||||||
import org.joinmastodon.android.BuildConfig;
|
import org.joinmastodon.android.BuildConfig;
|
||||||
import org.joinmastodon.android.GlobalUserPreferences;
|
import org.joinmastodon.android.GlobalUserPreferences;
|
||||||
import org.joinmastodon.android.MastodonApp;
|
|
||||||
import org.joinmastodon.android.R;
|
import org.joinmastodon.android.R;
|
||||||
import org.joinmastodon.android.api.MastodonAPIController;
|
import org.joinmastodon.android.api.MastodonAPIController;
|
||||||
import org.joinmastodon.android.api.session.AccountSession;
|
import org.joinmastodon.android.api.session.AccountSession;
|
||||||
|
@ -21,27 +32,26 @@ import org.joinmastodon.android.api.session.AccountSessionManager;
|
||||||
import org.joinmastodon.android.fragments.HasAccountID;
|
import org.joinmastodon.android.fragments.HasAccountID;
|
||||||
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
|
import org.joinmastodon.android.model.viewmodel.CheckableListItem;
|
||||||
import org.joinmastodon.android.model.viewmodel.ListItem;
|
import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||||
|
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
|
||||||
import org.joinmastodon.android.ui.Snackbar;
|
import org.joinmastodon.android.ui.Snackbar;
|
||||||
import org.joinmastodon.android.ui.utils.UiUtils;
|
import org.joinmastodon.android.ui.utils.UiUtils;
|
||||||
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
import org.joinmastodon.android.updater.GithubSelfUpdater;
|
||||||
|
import org.joinmastodon.android.utils.FileProvider;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.StringReader;
|
|
||||||
import java.nio.charset.Charset;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.FormatStyle;
|
import java.time.format.FormatStyle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import me.grishka.appkit.imageloader.ImageCache;
|
import me.grishka.appkit.imageloader.ImageCache;
|
||||||
|
@ -58,7 +68,7 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> impleme
|
||||||
private File crashLogFile=new File(MastodonApp.context.getFilesDir(), "crash.log");
|
private File crashLogFile=new File(MastodonApp.context.getFilesDir(), "crash.log");
|
||||||
|
|
||||||
// MOSHIDON
|
// MOSHIDON
|
||||||
private ListItem<Void> clearRecentEmojisItem;
|
private ListItem<Void> clearRecentEmojisItem, exportItem;
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
@ -73,6 +83,7 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> impleme
|
||||||
new ListItem<>(R.string.mo_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_repo_url))),
|
new ListItem<>(R.string.mo_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.mo_repo_url))),
|
||||||
new ListItem<>(R.string.settings_tos, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")),
|
new ListItem<>(R.string.settings_tos, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), "https://"+session.domain+"/terms")),
|
||||||
new ListItem<>(R.string.settings_privacy_policy, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.privacy_policy_url)), 0, true),
|
new ListItem<>(R.string.settings_privacy_policy, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.privacy_policy_url)), 0, true),
|
||||||
|
exportItem=new ListItem<>(R.string.export_settings_title, R.string.export_settings_summary, R.drawable.ic_fluent_arrow_export_24_filled, this::onExportClick),
|
||||||
clearRecentEmojisItem=new ListItem<>(R.string.mo_clear_recent_emoji, 0, this::onClearRecentEmojisClick),
|
clearRecentEmojisItem=new ListItem<>(R.string.mo_clear_recent_emoji, 0, this::onClearRecentEmojisClick),
|
||||||
mediaCacheItem=new ListItem<>(R.string.settings_clear_cache, 0, this::onClearMediaCacheClick),
|
mediaCacheItem=new ListItem<>(R.string.settings_clear_cache, 0, this::onClearMediaCacheClick),
|
||||||
new ListItem<>(getString(R.string.sk_settings_clear_timeline_cache), session.domain, this::onClearTimelineCacheClick),
|
new ListItem<>(getString(R.string.sk_settings_clear_timeline_cache), session.domain, this::onClearTimelineCacheClick),
|
||||||
|
@ -146,6 +157,43 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void> impleme
|
||||||
Toast.makeText(getContext(), R.string.mo_recent_emoji_cleared, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), R.string.mo_recent_emoji_cleared, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onExportClick(ListItem<?> item){
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonObject jsonObject = new JsonObject();
|
||||||
|
jsonObject.addProperty("versionName", BuildConfig.VERSION_NAME);
|
||||||
|
jsonObject.addProperty("versionCode", BuildConfig.VERSION_CODE);
|
||||||
|
|
||||||
|
// GlobalUserPreferences
|
||||||
|
//TODO: remove prefs that should not be exported
|
||||||
|
JsonElement je = gson.toJsonTree(GlobalUserPreferences.getPrefs().getAll());
|
||||||
|
jsonObject.add("GlobalUserPreferences", je);
|
||||||
|
|
||||||
|
// add account local prefs
|
||||||
|
for(AccountSession accountSession: AccountSessionManager.getInstance().getLoggedInAccounts()) {
|
||||||
|
Map<String, ?> prefs = accountSession.getRawLocalPreferences().getAll();
|
||||||
|
//TODO: remove prefs that should not be exported
|
||||||
|
JsonElement accountPrefs = gson.toJsonTree(prefs);
|
||||||
|
jsonObject.add(accountSession.self.id, accountPrefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
File file = new File(getContext().getCacheDir(), "moshidon-exported-settings.json");
|
||||||
|
FileWriter writer = new FileWriter(file);
|
||||||
|
writer.write(jsonObject.toString());
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
|
||||||
|
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||||
|
intent.setType("application/json");
|
||||||
|
Uri outputUri = FileProvider.getUriForFile(getContext(), getContext().getPackageName() + ".fileprovider", file);
|
||||||
|
intent.putExtra(Intent.EXTRA_STREAM, outputUri);
|
||||||
|
startActivity(Intent.createChooser(intent, getContext().getString(R.string.export_settings_share)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Toast.makeText(getContext(), getContext().getString(R.string.export_settings_fail), Toast.LENGTH_SHORT).show();
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateMediaCacheItem(){
|
private void updateMediaCacheItem(){
|
||||||
long size=ImageCache.getInstance(getActivity()).getDiskCache().size();
|
long size=ImageCache.getInstance(getActivity()).getDiskCache().size();
|
||||||
mediaCacheItem.subtitle=UiUtils.formatFileSize(getActivity(), size, false);
|
mediaCacheItem.subtitle=UiUtils.formatFileSize(getActivity(), size, false);
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<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="M2.75,4.504a0.75,0.75 0,0 1,0.743 0.648l0.007,0.102v13.499a0.75,0.75 0,0 1,-1.493 0.101L2,18.753v-13.5a0.75,0.75 0,0 1,0.75 -0.75ZM15.21,6.387 L15.293,6.293a1,1 0,0 1,1.32 -0.083l0.094,0.083 4.997,4.998a1,1 0,0 1,0.083 1.32l-0.083,0.093 -4.996,5.004a1,1 0,0 1,-1.499 -1.32l0.083,-0.094L18.581,13L6,13a1,1 0,0 1,-0.993 -0.883L5,12a1,1 0,0 1,0.883 -0.993L6,11h12.584l-3.291,-3.293a1,1 0,0 1,-0.083 -1.32l0.083,-0.094 -0.083,0.094Z"
|
||||||
|
android:fillColor="#212121"/>
|
||||||
|
</vector>
|
|
@ -120,4 +120,8 @@
|
||||||
<string name="mo_blocked_accounts">Blocked accounts</string>
|
<string name="mo_blocked_accounts">Blocked accounts</string>
|
||||||
<!-- <string name="mo_blocks">Blocks</string>-->
|
<!-- <string name="mo_blocks">Blocks</string>-->
|
||||||
<string name="mo_mute_notifications">Hide notifications from this user?</string>
|
<string name="mo_mute_notifications">Hide notifications from this user?</string>
|
||||||
|
<string name="export_settings_share">Export Settings</string>
|
||||||
|
<string name="export_settings_fail">Failed to export settings</string>
|
||||||
|
<string name="export_settings_title">Export settings</string>
|
||||||
|
<string name="export_settings_summary">Export all logged-in accounts\' settings and timelines</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue