parent
0c376d57e7
commit
d51e06b61f
|
@ -31,18 +31,44 @@ import org.joinmastodon.android.utils.ProvidesAssistContent;
|
||||||
import org.parceler.Parcels;
|
import org.parceler.Parcels;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
import me.grishka.appkit.FragmentStackActivity;
|
import me.grishka.appkit.FragmentStackActivity;
|
||||||
import me.grishka.appkit.Nav;
|
import me.grishka.appkit.Nav;
|
||||||
import me.grishka.appkit.api.Callback;
|
import me.grishka.appkit.api.Callback;
|
||||||
import me.grishka.appkit.api.ErrorResponse;
|
import me.grishka.appkit.api.ErrorResponse;
|
||||||
|
|
||||||
public class MainActivity extends FragmentStackActivity implements ProvidesAssistContent {
|
public class MainActivity extends FragmentStackActivity implements ProvidesAssistContent {
|
||||||
|
private static final String TAG="MainActivity";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState){
|
protected void onCreate(@Nullable Bundle savedInstanceState){
|
||||||
AccountSession session=getCurrentSession();
|
AccountSession session=getCurrentSession();
|
||||||
UiUtils.setUserPreferredTheme(this, session);
|
UiUtils.setUserPreferredTheme(this, session);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Thread.UncaughtExceptionHandler defaultHandler=Thread.getDefaultUncaughtExceptionHandler();
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler((t, e)->{
|
||||||
|
File file=new File(MastodonApp.context.getFilesDir(), "crash.log");
|
||||||
|
try(FileOutputStream out=new FileOutputStream(file)){
|
||||||
|
PrintWriter writer=new PrintWriter(out);
|
||||||
|
writer.println(BuildConfig.VERSION_NAME+" ("+BuildConfig.VERSION_CODE+")");
|
||||||
|
writer.println(Instant.now().toString());
|
||||||
|
writer.println();
|
||||||
|
e.printStackTrace(writer);
|
||||||
|
writer.flush();
|
||||||
|
}catch(IOException x){
|
||||||
|
Log.e(TAG, "Error writing crash.log", x);
|
||||||
|
}finally{
|
||||||
|
defaultHandler.uncaughtException(t, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if(savedInstanceState==null){
|
if(savedInstanceState==null){
|
||||||
restartHomeFragment();
|
restartHomeFragment();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.joinmastodon.android.fragments.settings;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -9,6 +10,7 @@ import android.widget.Toast;
|
||||||
|
|
||||||
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;
|
||||||
|
@ -18,6 +20,19 @@ import org.joinmastodon.android.model.viewmodel.ListItem;
|
||||||
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 java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
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.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.time.format.FormatStyle;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -28,10 +43,12 @@ import me.grishka.appkit.utils.SingleViewRecyclerAdapter;
|
||||||
import me.grishka.appkit.utils.V;
|
import me.grishka.appkit.utils.V;
|
||||||
|
|
||||||
public class SettingsAboutAppFragment extends BaseSettingsFragment<Void>{
|
public class SettingsAboutAppFragment extends BaseSettingsFragment<Void>{
|
||||||
private ListItem<Void> mediaCacheItem;
|
private static final String TAG="SettingsAboutAppFragment";
|
||||||
|
private ListItem<Void> mediaCacheItem, copyCrashLogItem;
|
||||||
private CheckableListItem<Void> enablePreReleasesItem;
|
private CheckableListItem<Void> enablePreReleasesItem;
|
||||||
private AccountSession session;
|
private AccountSession session;
|
||||||
private boolean timelineCacheCleared=false;
|
private boolean timelineCacheCleared=false;
|
||||||
|
private File crashLogFile=new File(MastodonApp.context.getFilesDir(), "crash.log");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState){
|
public void onCreate(Bundle savedInstanceState){
|
||||||
|
@ -39,19 +56,24 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void>{
|
||||||
setTitle(getString(R.string.about_app, getString(R.string.sk_app_name)));
|
setTitle(getString(R.string.about_app, getString(R.string.sk_app_name)));
|
||||||
session=AccountSessionManager.get(accountID);
|
session=AccountSessionManager.get(accountID);
|
||||||
|
|
||||||
|
String lastModified=crashLogFile.exists()
|
||||||
|
? DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG, FormatStyle.SHORT).withZone(ZoneId.systemDefault()).format(Instant.ofEpochMilli(crashLogFile.lastModified()))
|
||||||
|
: getString(R.string.sk_settings_crash_log_unavailable);
|
||||||
List<ListItem<Void>> items=new ArrayList<>(List.of(
|
List<ListItem<Void>> items=new ArrayList<>(List.of(
|
||||||
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, i->UiUtils.openHashtagTimeline(getActivity(), accountID, getString(R.string.donate_hashtag))),
|
new ListItem<>(R.string.sk_settings_donate, 0, R.drawable.ic_fluent_heart_24_regular, i->UiUtils.openHashtagTimeline(getActivity(), accountID, getString(R.string.donate_hashtag))),
|
||||||
new ListItem<>(R.string.sk_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.repo_url))),
|
new ListItem<>(R.string.sk_settings_contribute, 0, R.drawable.ic_fluent_open_24_regular, i->UiUtils.launchWebBrowser(getActivity(), getString(R.string.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),
|
||||||
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),
|
||||||
|
copyCrashLogItem=new ListItem<>(getString(R.string.sk_settings_copy_crash_log), lastModified, 0, this::onCopyCrashLog)
|
||||||
));
|
));
|
||||||
|
|
||||||
if(GithubSelfUpdater.needSelfUpdating()){
|
if(GithubSelfUpdater.needSelfUpdating()){
|
||||||
items.add(enablePreReleasesItem=new CheckableListItem<>(R.string.sk_updater_enable_pre_releases, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.enablePreReleases, i->toggleCheckableItem(enablePreReleasesItem)));
|
items.add(enablePreReleasesItem=new CheckableListItem<>(R.string.sk_updater_enable_pre_releases, 0, CheckableListItem.Style.SWITCH, GlobalUserPreferences.enablePreReleases, i->toggleCheckableItem(enablePreReleasesItem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copyCrashLogItem.isEnabled=crashLogFile.exists();
|
||||||
onDataLoaded(items);
|
onDataLoaded(items);
|
||||||
updateMediaCacheItem();
|
updateMediaCacheItem();
|
||||||
}
|
}
|
||||||
|
@ -107,4 +129,17 @@ public class SettingsAboutAppFragment extends BaseSettingsFragment<Void>{
|
||||||
mediaCacheItem.isEnabled=size>0;
|
mediaCacheItem.isEnabled=size>0;
|
||||||
rebindItem(mediaCacheItem);
|
rebindItem(mediaCacheItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onCopyCrashLog(ListItem<?> item){
|
||||||
|
if(!crashLogFile.exists()) return;
|
||||||
|
try(InputStream is=new FileInputStream(crashLogFile)){
|
||||||
|
BufferedReader reader=new BufferedReader(new InputStreamReader(is));
|
||||||
|
StringBuilder sb=new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line=reader.readLine())!=null) sb.append(line).append("\n");
|
||||||
|
UiUtils.copyText(list, sb.toString());
|
||||||
|
} catch(IOException e){
|
||||||
|
Log.e(TAG, "Error reading crash log", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -430,4 +430,7 @@
|
||||||
<string name="sk_private_note_confirm_delete">Delete personal note about %s?</string>
|
<string name="sk_private_note_confirm_delete">Delete personal note about %s?</string>
|
||||||
<string name="sk_delete_note">Delete personal note</string>
|
<string name="sk_delete_note">Delete personal note</string>
|
||||||
<string name="sk_add_note">Add personal note</string>
|
<string name="sk_add_note">Add personal note</string>
|
||||||
|
<string name="sk_settings_copy_crash_log">Copy latest crash log</string>
|
||||||
|
<string name="sk_settings_crash_log_unavailable">None available… yet</string>
|
||||||
|
<string name="sk_crash_log_copied">Crash log copied</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue