implement url opening

use activity lifecycle callbacks to track foreground state
use labdas for the chansettings
multisite
Floens 8 years ago
parent 839ab5d55b
commit 182da4604c
  1. 1
      Clover/app/src/main/AndroidManifest.xml
  2. 40
      Clover/app/src/main/java/org/floens/chan/Chan.java
  3. 84
      Clover/app/src/main/java/org/floens/chan/chan/ChanHelper.java
  4. 35
      Clover/app/src/main/java/org/floens/chan/core/database/LoadableProvider.java
  5. 2
      Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java
  6. 48
      Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java
  7. 2
      Clover/app/src/main/java/org/floens/chan/core/site/Resolvable.java
  8. 4
      Clover/app/src/main/java/org/floens/chan/core/site/Site.java
  9. 3
      Clover/app/src/main/java/org/floens/chan/core/site/SiteBase.java
  10. 2
      Clover/app/src/main/java/org/floens/chan/core/site/SiteManager.java
  11. 72
      Clover/app/src/main/java/org/floens/chan/core/site/SiteResolver.java
  12. 6
      Clover/app/src/main/java/org/floens/chan/core/site/http/HttpCallManager.java
  13. 68
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan4/Chan4.java
  14. 64
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
  15. 148
      Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java

@ -72,6 +72,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
<data android:host="4chan.org" />
<data android:host="www.4chan.org" />
<data android:host="boards.4chan.org" />
<data android:host="8ch.net" />
</intent-filter>
</activity>

@ -18,9 +18,11 @@
package org.floens.chan;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import org.floens.chan.core.database.DatabaseManager;
@ -39,7 +41,7 @@ import javax.inject.Inject;
import dagger.ObjectGraph;
import de.greenrobot.event.EventBus;
public class Chan extends Application implements UserAgentProvider {
public class Chan extends Application implements UserAgentProvider, Application.ActivityLifecycleCallbacks {
private static final String TAG = "ChanApplication";
@SuppressLint("StaticFieldLeak")
@ -78,6 +80,8 @@ public class Chan extends Application implements UserAgentProvider {
final long startTime = Time.startTiming();
registerActivityLifecycleCallbacks(this);
AndroidUtils.init();
userAgent = createUserAgent();
@ -118,7 +122,7 @@ public class Chan extends Application implements UserAgentProvider {
return userAgent;
}
public void activityEnteredForeground() {
private void activityEnteredForeground() {
boolean lastForeground = getApplicationInForeground();
activityForegroundCounter++;
@ -128,7 +132,7 @@ public class Chan extends Application implements UserAgentProvider {
}
}
public void activityEnteredBackground() {
private void activityEnteredBackground() {
boolean lastForeground = getApplicationInForeground();
activityForegroundCounter--;
@ -164,4 +168,34 @@ public class Chan extends Application implements UserAgentProvider {
version = version.toLowerCase(Locale.ENGLISH).replace(" ", "_");
return getString(R.string.app_name) + "/" + version;
}
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
@Override
public void onActivityStarted(Activity activity) {
activityEnteredForeground();
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
activityEnteredBackground();
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
}

@ -1,84 +0,0 @@
/*
* Clover - 4chan browser https://github.com/Floens/Clover/
* Copyright (C) 2014 Floens
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.floens.chan.chan;
import android.net.Uri;
import org.floens.chan.core.database.DatabaseLoadableManager;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.model.orm.Board;
import org.floens.chan.core.model.orm.Loadable;
import org.floens.chan.core.site.Site;
import org.floens.chan.core.site.Sites;
import java.util.List;
import static org.floens.chan.Chan.getGraph;
public class ChanHelper {
public static Loadable getLoadableFromStartUri(Uri uri) {
Loadable loadable = null;
List<String> parts = uri.getPathSegments();
// TODO(multi-site) get correct site
Site site = Sites.defaultSite();
if (parts.size() > 0) {
String rawBoard = parts.get(0);
DatabaseManager databaseManager = getGraph().get(DatabaseManager.class);
DatabaseLoadableManager loadableManager = databaseManager.getDatabaseLoadableManager();
Board board = site.board(rawBoard);
if (board != null) {
if (parts.size() == 1 || (parts.size() == 2 && "catalog".equals(parts.get(1)))) {
// Board mode
loadable = loadableManager.get(Loadable.forCatalog(board));
} else if (parts.size() >= 3) {
// Thread mode
int no = -1;
try {
no = Integer.parseInt(parts.get(2));
} catch (NumberFormatException ignored) {
}
int post = -1;
String fragment = uri.getFragment();
if (fragment != null) {
int index = fragment.indexOf("p");
if (index >= 0) {
try {
post = Integer.parseInt(fragment.substring(index + 1));
} catch (NumberFormatException ignored) {
}
}
}
if (no >= 0) {
loadable = loadableManager.get(Loadable.forThread(site, board, no));
if (post >= 0) {
loadable.markedNo = post;
}
}
}
}
}
return loadable;
}
}

@ -0,0 +1,35 @@
/*
* Clover - 4chan browser https://github.com/Floens/Clover/
* Copyright (C) 2014 Floens
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.floens.chan.core.database;
import org.floens.chan.core.model.orm.Loadable;
import javax.inject.Inject;
public class LoadableProvider {
private DatabaseManager databaseManager;
@Inject
public LoadableProvider(DatabaseManager databaseManager) {
this.databaseManager = databaseManager;
}
public Loadable get(Loadable definition) {
return databaseManager.getDatabaseLoadableManager().get(definition);
}
}

@ -9,6 +9,7 @@ import org.floens.chan.ChanApplication;
import org.floens.chan.chan.ChanLoader;
import org.floens.chan.core.cache.FileCache;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.database.LoadableProvider;
import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.manager.FilterEngine;
import org.floens.chan.core.manager.ReplyManager;
@ -61,6 +62,7 @@ import dagger.Provides;
ImageLoader.class,
FileCache.class,
HttpCallManager.class,
LoadableProvider.class,
ChanApplication.class,
MainSettingsController.class,

@ -188,12 +188,8 @@ public class ChanSettings {
developer = new BooleanSetting(p, "preference_developer", false);
saveLocation = new StringSetting(p, "preference_image_save_location", Environment.getExternalStorageDirectory() + File.separator + "Clover");
saveLocation.addCallback(new Setting.SettingCallback<String>() {
@Override
public void onValueChange(Setting setting, String value) {
EventBus.getDefault().post(new SettingChanged<>(saveLocation));
}
});
saveLocation.addCallback((setting, value) ->
EventBus.getDefault().post(new SettingChanged<>(saveLocation)));
saveOriginalFilename = new BooleanSetting(p, "preference_image_save_original", false);
shareUrl = new BooleanSetting(p, "preference_image_share_url", false);
networkHttps = new BooleanSetting(p, "preference_network_https", true);
@ -209,26 +205,18 @@ public class ChanSettings {
volumeKeysScrolling = new BooleanSetting(p, "preference_volume_key_scrolling", false);
postFullDate = new BooleanSetting(p, "preference_post_full_date", false);
postFileInfo = new BooleanSetting(p, "preference_post_file_info", true);
postFilename = new BooleanSetting(p, "preference_post_filename", false);
postFilename = new BooleanSetting(p, "preference_post_filename", true);
neverHideToolbar = new BooleanSetting(p, "preference_never_hide_toolbar", false);
controllerSwipeable = new BooleanSetting(p, "preference_controller_swipeable", true);
saveBoardFolder = new BooleanSetting(p, "preference_save_subboard", false);
watchEnabled = new BooleanSetting(p, "preference_watch_enabled", false);
watchEnabled.addCallback(new Setting.SettingCallback<Boolean>() {
@Override
public void onValueChange(Setting setting, Boolean value) {
EventBus.getDefault().post(new SettingChanged<>(watchEnabled));
}
});
watchEnabled.addCallback((setting, value) ->
EventBus.getDefault().post(new SettingChanged<>(watchEnabled)));
watchCountdown = new BooleanSetting(p, "preference_watch_countdown", false);
watchBackground = new BooleanSetting(p, "preference_watch_background_enabled", false);
watchBackground.addCallback(new Setting.SettingCallback<Boolean>() {
@Override
public void onValueChange(Setting setting, Boolean value) {
EventBus.getDefault().post(new SettingChanged<>(watchBackground));
}
});
watchBackground.addCallback((setting, value) ->
EventBus.getDefault().post(new SettingChanged<>(watchBackground)));
watchBackgroundInterval = new IntegerSetting(p, "preference_watch_background_interval", WatchManager.DEFAULT_BACKGROUND_INTERVAL);
watchNotifyMode = new StringSetting(p, "preference_watch_notify_mode", "all");
watchSound = new StringSetting(p, "preference_watch_sound", "quotes");
@ -240,26 +228,12 @@ public class ChanSettings {
previousVersion = new IntegerSetting(p, "preference_previous_version", 0);
proxyEnabled = new BooleanSetting(p, "preference_proxy_enabled", false);
proxyEnabled.addCallback(new Setting.SettingCallback<Boolean>() {
@Override
public void onValueChange(Setting setting, Boolean value) {
loadProxy();
}
});
proxyAddress = new StringSetting(p, "preference_proxy_address", "");
proxyAddress.addCallback(new Setting.SettingCallback<String>() {
@Override
public void onValueChange(Setting setting, String value) {
loadProxy();
}
});
proxyPort = new IntegerSetting(p, "preference_proxy_port", 80);
proxyPort.addCallback(new Setting.SettingCallback<Integer>() {
@Override
public void onValueChange(Setting setting, Integer value) {
loadProxy();
}
});
proxyEnabled.addCallback((setting, value) -> loadProxy());
proxyAddress.addCallback((setting, value) -> loadProxy());
proxyPort.addCallback((setting, value) -> loadProxy());
loadProxy();
settingsOpenCounter = new CounterSetting(p, "counter_settings_open");

@ -8,7 +8,7 @@ public interface Resolvable {
FULL_MATCH
}
ResolveResult resolve(String value);
ResolveResult matchesName(String value);
Class<? extends Site> getSiteClass();
}

@ -33,6 +33,8 @@ import org.floens.chan.core.site.http.LoginResponse;
import org.floens.chan.core.site.http.Reply;
import org.floens.chan.core.site.http.ReplyResponse;
import okhttp3.HttpUrl;
public interface Site {
enum Feature {
/**
@ -129,6 +131,8 @@ public interface Site {
SiteIcon icon();
Loadable respondsTo(HttpUrl url);
boolean feature(Feature feature);
boolean boardFeature(BoardFeature boardFeature, Board board);

@ -20,6 +20,7 @@ package org.floens.chan.core.site;
import com.android.volley.RequestQueue;
import org.floens.chan.core.database.LoadableProvider;
import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.model.json.site.SiteConfig;
import org.floens.chan.core.model.json.site.SiteUserSettings;
@ -40,6 +41,7 @@ public abstract class SiteBase implements Site {
protected HttpCallManager httpCallManager;
protected RequestQueue requestQueue;
protected BoardManager boardManager;
protected LoadableProvider loadableProvider;
@Override
public void initialize(int id, SiteConfig config, SiteUserSettings userSettings) {
@ -55,6 +57,7 @@ public abstract class SiteBase implements Site {
httpCallManager = graph.get(HttpCallManager.class);
requestQueue = graph.get(RequestQueue.class);
boardManager = graph.get(BoardManager.class);
loadableProvider = graph.get(LoadableProvider.class);
if (boardsType() == BoardsType.DYNAMIC) {
boards(boards -> boardManager.createAll(boards.boards));

@ -47,7 +47,7 @@ public class SiteManager {
}
public void addSite(String url, SiteAddCallback callback) {
SiteResolver.SiteResolverResult resolve = resolver.resolve(url);
SiteResolver.SiteResolverResult resolve = resolver.resolveSiteForUrl(url);
Class<? extends Site> siteClass;
if (resolve.match == SiteResolver.SiteResolverResult.Match.BUILTIN) {

@ -18,35 +18,33 @@
package org.floens.chan.core.site;
import android.support.annotation.Nullable;
import org.floens.chan.core.database.LoadableProvider;
import org.floens.chan.core.model.orm.Loadable;
import java.util.List;
import javax.inject.Inject;
import okhttp3.HttpUrl;
class SiteResolver {
public class SiteResolver {
private LoadableProvider loadableProvider;
@Inject
public SiteResolver() {
public SiteResolver(LoadableProvider loadableProvider) {
this.loadableProvider = loadableProvider;
}
SiteResolverResult resolve(String url) {
SiteResolverResult resolveSiteForUrl(String url) {
List<Resolvable> resolvables = Sites.RESOLVABLES;
HttpUrl httpUrl = HttpUrl.parse(url);
if (httpUrl == null) {
httpUrl = HttpUrl.parse("https://" + url);
}
if (httpUrl != null) {
if (httpUrl.host().indexOf('.') < 0) {
httpUrl = null;
}
}
HttpUrl httpUrl = sanitizeUrl(url);
if (httpUrl == null) {
for (Resolvable resolvable : resolvables) {
if (resolvable.resolve(url) == Resolvable.ResolveResult.NAME_MATCH) {
if (resolvable.matchesName(url) == Resolvable.ResolveResult.NAME_MATCH) {
return new SiteResolverResult(SiteResolverResult.Match.BUILTIN, resolvable.getSiteClass(), null);
}
}
@ -59,7 +57,7 @@ class SiteResolver {
}
for (Resolvable resolvable : resolvables) {
if (resolvable.resolve(httpUrl.toString()) == Resolvable.ResolveResult.FULL_MATCH) {
if (resolvable.matchesName(httpUrl.toString()) == Resolvable.ResolveResult.FULL_MATCH) {
return new SiteResolverResult(SiteResolverResult.Match.BUILTIN, resolvable.getSiteClass(), null);
}
}
@ -67,6 +65,40 @@ class SiteResolver {
return new SiteResolverResult(SiteResolverResult.Match.EXTERNAL, null, httpUrl);
}
public LoadableResult resolveLoadableForUrl(String url) {
final HttpUrl httpUrl = sanitizeUrl(url);
if (httpUrl == null) {
return null;
}
for (Site site : Sites.allSites()) {
Loadable resolved = site.respondsTo(httpUrl);
if (resolved != null) {
return new LoadableResult(resolved);
}
}
return null;
}
@Nullable
private HttpUrl sanitizeUrl(String url) {
HttpUrl httpUrl = HttpUrl.parse(url);
if (httpUrl == null) {
httpUrl = HttpUrl.parse("https://" + url);
}
if (httpUrl != null) {
if (httpUrl.host().indexOf('.') < 0) {
httpUrl = null;
}
}
return httpUrl;
}
static class SiteResolverResult {
enum Match {
NONE,
@ -84,4 +116,12 @@ class SiteResolver {
this.externalResult = externalResult;
}
}
public static class LoadableResult {
public final Loadable loadable;
public LoadableResult(Loadable loadable) {
this.loadable = loadable;
}
}
}

@ -20,6 +20,7 @@ package org.floens.chan.core.site.http;
import org.floens.chan.core.di.UserAgentProvider;
import org.floens.chan.core.site.Site;
import org.floens.chan.core.site.SiteRequestModifier;
import java.util.concurrent.TimeUnit;
@ -58,7 +59,10 @@ public class HttpCallManager {
httpCall.setup(requestBuilder);
if (site != null) {
site.requestModifier().modifyHttpCall(httpCall, requestBuilder);
final SiteRequestModifier siteRequestModifier = site.requestModifier();
if (siteRequestModifier != null) {
siteRequestModifier.modifyHttpCall(httpCall, requestBuilder);
}
}
requestBuilder.header("User-Agent", userAgentProvider.getUserAgent());

@ -59,13 +59,14 @@ import okhttp3.Request;
public class Chan4 extends SiteBase {
public static final Resolvable RESOLVABLE = new Resolvable() {
@Override
public ResolveResult resolve(String value) {
if (value.equals("4chan")) {
return ResolveResult.NAME_MATCH;
} else if (value.equals("https://4chan.org/")) {
return ResolveResult.FULL_MATCH;
} else {
return ResolveResult.NO;
public ResolveResult matchesName(String value) {
switch (value) {
case "4chan":
return ResolveResult.NAME_MATCH;
case "https://4chan.org/":
return ResolveResult.FULL_MATCH;
default:
return ResolveResult.NO;
}
}
@ -270,6 +271,59 @@ public class Chan4 extends SiteBase {
return SiteIcon.fromAssets("icons/4chan.png");
}
@Override
public Loadable respondsTo(HttpUrl url) {
boolean responds = url.host().equals("4chan.org") ||
url.host().equals("www.4chan.org") ||
url.host().equals("boards.4chan.org");
if (responds) {
List<String> parts = url.pathSegments();
if (!parts.isEmpty()) {
String boardCode = parts.get(0);
Board board = board(boardCode);
if (board != null) {
if (parts.size() < 3) {
// Board mode
return loadableProvider.get(Loadable.forCatalog(board));
} else if (parts.size() >= 3) {
// Thread mode
int no = -1;
try {
no = Integer.parseInt(parts.get(2));
} catch (NumberFormatException ignored) {
}
int post = -1;
String fragment = url.fragment();
if (fragment != null) {
int index = fragment.indexOf("p");
if (index >= 0) {
try {
post = Integer.parseInt(fragment.substring(index + 1));
} catch (NumberFormatException ignored) {
}
}
}
if (no >= 0) {
Loadable loadable = loadableProvider.get(
Loadable.forThread(this, board, no));
if (post >= 0) {
loadable.markedNo = post;
}
return loadable;
}
}
}
}
}
return null;
}
@Override
public boolean feature(Feature feature) {
switch (feature) {

@ -42,6 +42,7 @@ import org.floens.chan.core.site.http.LoginRequest;
import org.floens.chan.core.site.http.Reply;
import org.floens.chan.utils.Logger;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@ -55,13 +56,14 @@ public class Chan8 extends SiteBase {
public static final Resolvable RESOLVABLE = new Resolvable() {
@Override
public ResolveResult resolve(String value) {
if (value.equals("8chan")) {
return ResolveResult.NAME_MATCH;
} else if (value.equals("https://8ch.net/")) {
return ResolveResult.FULL_MATCH;
} else {
return ResolveResult.NO;
public ResolveResult matchesName(String value) {
switch (value) {
case "8chan":
return ResolveResult.NAME_MATCH;
case "https://8ch.net/":
return ResolveResult.FULL_MATCH;
default:
return ResolveResult.NO;
}
}
@ -184,6 +186,54 @@ public class Chan8 extends SiteBase {
return SiteIcon.fromAssets("icons/8chan.png");
}
@Override
public Loadable respondsTo(HttpUrl url) {
boolean responds = url.host().equals("8ch.net");
if (responds) {
List<String> parts = url.pathSegments();
if (!parts.isEmpty()) {
String boardCode = parts.get(0);
Board board = board(boardCode);
if (board != null) {
if (parts.size() < 3) {
// Board mode
return loadableProvider.get(Loadable.forCatalog(board));
} else if (parts.size() >= 3) {
// Thread mode
int no = -1;
try {
no = Integer.parseInt(parts.get(2).replace(".html", ""));
} catch (NumberFormatException ignored) {
}
int post = -1;
String fragment = url.fragment();
if (fragment != null) {
try {
post = Integer.parseInt(fragment);
} catch (NumberFormatException ignored) {
}
}
if (no >= 0) {
Loadable loadable = loadableProvider.get(
Loadable.forThread(this, board, no));
if (post >= 0) {
loadable.markedNo = post;
}
return loadable;
}
}
}
}
}
return null;
}
@Override
public boolean feature(Feature feature) {
switch (feature) {

@ -20,6 +20,7 @@ package org.floens.chan.ui.activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
@ -32,7 +33,6 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import org.floens.chan.Chan;
import org.floens.chan.R;
import org.floens.chan.controller.Controller;
import org.floens.chan.controller.NavigationController;
@ -45,6 +45,7 @@ import org.floens.chan.core.model.orm.Loadable;
import org.floens.chan.core.model.orm.Pin;
import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.core.site.Site;
import org.floens.chan.core.site.SiteResolver;
import org.floens.chan.core.site.Sites;
import org.floens.chan.ui.controller.BrowseController;
import org.floens.chan.ui.controller.DoubleNavigationController;
@ -94,6 +95,9 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
@Inject
WatchManager watchManager;
@Inject
SiteResolver siteResolver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -132,54 +136,16 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
}
private void setupFromStateOrFreshLaunch(Bundle savedInstanceState) {
boolean loadDefault = true;
/*if (savedInstanceState != null) {
// Restore the activity state from the previously saved state.
ChanState chanState = savedInstanceState.getParcelable(STATE_KEY);
if (chanState == null) {
Logger.w(TAG, "savedInstanceState was not null, but no ChanState was found!");
} else {
Pair<Loadable, Loadable> boardThreadPair = resolveChanState(chanState);
if (boardThreadPair != null && boardThreadPair.first != null) {
loadDefault = false;
browseController.setBoard(boardThreadPair.first.board);
if (boardThreadPair.second != null) {
browseController.showThread(boardThreadPair.second);
}
}
}
boolean handled;
if (savedInstanceState != null) {
handled = restoreFromSavedState(savedInstanceState);
} else {
final Uri data = getIntent().getData();
// Start from an url launch.
if (data != null) {
Loadable fromUri = ChanHelper.getLoadableFromStartUri(data);
if (fromUri != null) {
loadDefault = false;
browseController.setBoard(fromUri.board);
if (fromUri.isThreadMode()) {
browseController.showThread(fromUri, false);
}
} else {
new AlertDialog.Builder(this)
.setMessage(R.string.open_link_not_matched)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
AndroidUtils.openLink(data.toString());
}
})
.show();
}
}
}*/
handled = restoreFromUrl();
}
// Not from a state or from an url, launch the setup controller if no boards are setup up yet,
// otherwise load the default saved board.
if (loadDefault) {
if (!handled) {
/*if (boardManager.getSavedBoards().isEmpty()) {
setupWithNoBoards();
} else {
@ -189,6 +155,60 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
}
}
private boolean restoreFromUrl() {
boolean handled = false;
final Uri data = getIntent().getData();
// Start from an url launch.
if (data != null) {
final SiteResolver.LoadableResult loadableResult =
siteResolver.resolveLoadableForUrl(data.toString());
if (loadableResult != null) {
handled = true;
Loadable loadable = loadableResult.loadable;
browseController.setBoard(loadable.board);
if (loadable.isThreadMode()) {
browseController.showThread(loadable, false);
}
} else {
new AlertDialog.Builder(this)
.setMessage(R.string.open_link_not_matched)
.setPositiveButton(R.string.ok, (dialog, which) ->
AndroidUtils.openLink(data.toString()))
.show();
}
}
return handled;
}
private boolean restoreFromSavedState(Bundle savedInstanceState) {
boolean handled = true;
// Restore the activity state from the previously saved state.
ChanState chanState = savedInstanceState.getParcelable(STATE_KEY);
if (chanState == null) {
Logger.w(TAG, "savedInstanceState was not null, but no ChanState was found!");
} else {
Pair<Loadable, Loadable> boardThreadPair = resolveChanState(chanState);
if (boardThreadPair != null && boardThreadPair.first != null) {
handled = true;
browseController.setBoard(boardThreadPair.first.board);
if (boardThreadPair.second != null) {
browseController.showThread(boardThreadPair.second);
}
}
}
return handled;
}
private void setupWithNoBoards() {
mainNavigationController.presentController(new SetupController(this), false);
}
@ -197,17 +217,19 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
DatabaseLoadableManager loadableManager = databaseManager.getDatabaseLoadableManager();
Site site = Sites.forId(state.board.siteId);
Board board = site.board(state.board.boardCode);
if (board != null) {
state.board.site = site;
state.board.board = board;
state.thread.site = site;
state.thread.board = board;
Loadable boardLoadable = loadableManager.get(state.board);
Loadable threadLoadable = loadableManager.get(state.thread);
return new Pair<>(boardLoadable, threadLoadable.mode == Loadable.Mode.THREAD ? threadLoadable : null);
if (site != null) {
Board board = site.board(state.board.boardCode);
if (board != null) {
state.board.site = site;
state.board.board = board;
state.thread.site = site;
state.thread.board = board;
Loadable boardLoadable = loadableManager.get(state.board);
Loadable threadLoadable = loadableManager.get(state.thread);
return new Pair<>(boardLoadable, threadLoadable.mode == Loadable.Mode.THREAD ? threadLoadable : null);
}
}
return null;
@ -431,20 +453,6 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
stack.clear();
}
@Override
protected void onStart() {
super.onStart();
Chan.getInstance().activityEnteredForeground();
}
@Override
protected void onStop() {
super.onStop();
Chan.getInstance().activityEnteredBackground();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Loading…
Cancel
Save