multisite
Floens 9 years ago
parent 3a652cf51e
commit 33c5cc720e
  1. 2
      Clover/app/build.gradle
  2. 43
      Clover/app/src/main/java/org/floens/chan/Chan.java
  3. 3
      Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java
  4. 15
      Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java
  5. 5
      Clover/app/src/main/java/org/floens/chan/core/UserAgentProvider.java
  6. 5
      Clover/app/src/main/java/org/floens/chan/core/database/DatabaseManager.java
  7. 33
      Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java
  8. 33
      Clover/app/src/main/java/org/floens/chan/core/di/ChanGraph.java
  9. 10
      Clover/app/src/main/java/org/floens/chan/core/http/ReplyManager.java
  10. 5
      Clover/app/src/main/java/org/floens/chan/core/manager/BoardManager.java
  11. 5
      Clover/app/src/main/java/org/floens/chan/core/manager/WatchManager.java
  12. 6
      Clover/app/src/main/java/org/floens/chan/core/model/Post.java
  13. 12
      Clover/app/src/main/java/org/floens/chan/core/net/ChanReaderRequest.java
  14. 24
      Clover/app/src/main/java/org/floens/chan/core/presenter/ReplyPresenter.java
  15. 13
      Clover/app/src/main/java/org/floens/chan/ui/controller/DeveloperSettingsController.java
  16. 8
      Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java
  17. 4
      Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java
  18. 9
      Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java
  19. 2
      Clover/build.gradle

@ -99,4 +99,6 @@ dependencies {
compile 'com.davemorrissey.labs:subsampling-scale-image-view:3.5.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'de.greenrobot:eventbus:2.4.0'
compile 'com.google.dagger:dagger:2.2'
annotationProcessor 'com.google.dagger:dagger-compiler:2.2'
}

@ -27,8 +27,12 @@ import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
import org.floens.chan.core.UserAgentProvider;
import org.floens.chan.core.cache.FileCache;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.di.AppModule;
import org.floens.chan.core.di.ChanGraph;
import org.floens.chan.core.di.DaggerChanGraph;
import org.floens.chan.core.http.ReplyManager;
import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.manager.WatchManager;
@ -41,9 +45,11 @@ import org.floens.chan.utils.Time;
import java.io.File;
import java.util.Locale;
import javax.inject.Inject;
import de.greenrobot.event.EventBus;
public class Chan extends Application {
public class Chan extends Application implements UserAgentProvider {
private static final String TAG = "ChanApplication";
private static final long FILE_CACHE_DISK_SIZE = 50 * 1024 * 1024;
@ -55,15 +61,16 @@ public class Chan extends Application {
private static Chan instance;
private static RequestQueue volleyRequestQueue;
private static ImageLoader imageLoader;
private static BoardManager boardManager;
private static WatchManager watchManager;
private static ReplyManager replyManager;
private static DatabaseManager databaseManager;
private static FileCache fileCache;
private String userAgent;
private int activityForegroundCounter = 0;
protected ChanGraph graph;
@Inject
DatabaseManager databaseManager;
public Chan() {
instance = this;
con = this;
@ -82,25 +89,29 @@ public class Chan extends Application {
}
public static BoardManager getBoardManager() {
return boardManager;
throw new IllegalArgumentException();
}
public static WatchManager getWatchManager() {
return watchManager;
throw new IllegalArgumentException();
}
public static ReplyManager getReplyManager() {
return replyManager;
throw new IllegalArgumentException();
}
public static DatabaseManager getDatabaseManager() {
return databaseManager;
throw new IllegalArgumentException();
}
public static FileCache getFileCache() {
return fileCache;
}
public static ChanGraph getGraph() {
return instance.graph;
}
@Override
public void onCreate() {
super.onCreate();
@ -108,13 +119,16 @@ public class Chan extends Application {
final long startTime = Time.startTiming();
AndroidUtils.init();
graph = DaggerChanGraph.builder()
.appModule(new AppModule(this, this))
.build();
graph.inject(this);
userAgent = createUserAgent();
File cacheDir = getExternalCacheDir() != null ? getExternalCacheDir() : getCacheDir();
replyManager = new ReplyManager(this, userAgent);
volleyRequestQueue = Volley.newRequestQueue(this, userAgent, new ProxiedHurlStack(userAgent), new File(cacheDir, Volley.DEFAULT_CACHE_DIR), VOLLEY_CACHE_SIZE);
final int runtimeMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
@ -124,9 +138,9 @@ public class Chan extends Application {
fileCache = new FileCache(new File(cacheDir, FILE_CACHE_NAME), FILE_CACHE_DISK_SIZE, getUserAgent());
databaseManager = new DatabaseManager(this);
boardManager = new BoardManager(databaseManager);
watchManager = new WatchManager(databaseManager);
// sDatabaseManager = new DatabaseManager(this);
// boardManager = new BoardManager(null);
// watchManager = new WatchManager(null);
Time.endTiming("Initializing application", startTime);
@ -153,6 +167,7 @@ public class Chan extends Application {
}
}
@Override
public String getUserAgent() {
return userAgent;
}

@ -24,7 +24,6 @@ import com.android.volley.Response;
import com.android.volley.VolleyError;
import org.floens.chan.Chan;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.exception.ChanLoaderException;
import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable;
@ -51,7 +50,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
private final List<ChanLoaderCallback> listeners = new ArrayList<>();
private final Loadable loadable;
private final RequestQueue volleyRequestQueue;
private final DatabaseManager databaseManager;
private ChanThread thread;
private ChanReaderRequest request;
@ -69,7 +67,6 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener<Cha
}
volleyRequestQueue = Chan.getVolleyRequestQueue();
databaseManager = Chan.getDatabaseManager();
}
/**

@ -27,7 +27,6 @@ import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.text.style.UnderlineSpan;
import org.floens.chan.Chan;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable;
@ -54,21 +53,21 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
import static org.floens.chan.utils.AndroidUtils.sp;
@Singleton
public class ChanParser {
private static final String TAG = "ChanParser";
private static final Pattern colorPattern = Pattern.compile("color:#([0-9a-fA-F]*)");
private static ChanParser instance = new ChanParser();
private final DatabaseManager databaseManager;
@Inject
DatabaseManager databaseManager;
@Inject
public ChanParser() {
databaseManager = Chan.getDatabaseManager();
}
public static ChanParser getInstance() {
return instance;
}
public void parse(Post post) {

@ -0,0 +1,5 @@
package org.floens.chan.core;
public interface UserAgentProvider {
String getUserAgent();
}

@ -41,6 +41,9 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.inject.Inject;
import javax.inject.Singleton;
import de.greenrobot.event.EventBus;
/**
@ -51,6 +54,7 @@ import de.greenrobot.event.EventBus;
* You often want the sync flavour for queries that return data, it waits for the task to be finished on the other thread.<br>
* Use the async versions when you don't care when the query is done.
*/
@Singleton
public class DatabaseManager {
private static final String TAG = "DatabaseManager";
@ -70,6 +74,7 @@ public class DatabaseManager {
private final DatabaseFilterManager databaseFilterManager;
private final DatabaseBoardManager databaseBoardManager;
@Inject
public DatabaseManager(Context context) {
backgroundExecutor = Executors.newSingleThreadExecutor();

@ -0,0 +1,33 @@
package org.floens.chan.core.di;
import android.content.Context;
import org.floens.chan.core.UserAgentProvider;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class AppModule {
private Context applicationContext;
private UserAgentProvider userAgentProvider;
public AppModule(Context applicationContext, UserAgentProvider userAgentProvider) {
this.applicationContext = applicationContext;
this.userAgentProvider = userAgentProvider;
}
@Provides
@Singleton
public Context provideApplicationContext() {
return applicationContext;
}
@Provides
@Singleton
public UserAgentProvider provideUserAgentProvider() {
return userAgentProvider;
}
}

@ -0,0 +1,33 @@
package org.floens.chan.core.di;
import org.floens.chan.Chan;
import org.floens.chan.chan.ChanParser;
import org.floens.chan.core.net.ChanReaderRequest;
import org.floens.chan.core.presenter.ReplyPresenter;
import org.floens.chan.ui.controller.DeveloperSettingsController;
import org.floens.chan.ui.controller.MainSettingsController;
import org.floens.chan.ui.layout.ThreadLayout;
import javax.inject.Singleton;
import dagger.Component;
@Component(modules = {
AppModule.class
})
@Singleton
public interface ChanGraph {
void inject(Chan chan);
void inject(MainSettingsController mainSettingsController);
void inject(ReplyPresenter replyPresenter);
void inject(ChanReaderRequest chanReaderRequest);
void inject(ThreadLayout threadLayout);
void inject(DeveloperSettingsController developerSettingsController);
ChanParser getChanParser();
}

@ -19,6 +19,7 @@ package org.floens.chan.core.http;
import android.content.Context;
import org.floens.chan.core.UserAgentProvider;
import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Reply;
@ -27,12 +28,16 @@ import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import javax.inject.Singleton;
import okhttp3.OkHttpClient;
import okhttp3.Request;
/**
* To send an reply to 4chan.
*/
@Singleton
public class ReplyManager {
private static final int TIMEOUT = 30000;
@ -42,9 +47,10 @@ public class ReplyManager {
private Map<Loadable, Reply> drafts = new HashMap<>();
public ReplyManager(Context context, String userAgent) {
@Inject
public ReplyManager(Context context, UserAgentProvider userAgentProvider) {
this.context = context;
this.userAgent = userAgent;
userAgent = userAgentProvider.getUserAgent();
client = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)

@ -30,8 +30,12 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import de.greenrobot.event.EventBus;
@Singleton
public class BoardManager {
private static final String TAG = "BoardManager";
@ -56,6 +60,7 @@ public class BoardManager {
private final List<Board> savedBoards = new ArrayList<>();
private final Map<String, Board> boardsByCode = new HashMap<>();
@Inject
public BoardManager(DatabaseManager databaseManager) {
this.databaseManager = databaseManager;
defaultSite = Sites.defaultSite();

@ -51,6 +51,9 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
import de.greenrobot.event.EventBus;
import static org.floens.chan.utils.AndroidUtils.getAppContext;
@ -70,6 +73,7 @@ import static org.floens.chan.utils.AndroidUtils.getAppContext;
* <p/>
* <p>All pin adding and removing must go through this class to properly update the watchers.
*/
@Singleton
public class WatchManager {
private static final String TAG = "WatchManager";
@ -124,6 +128,7 @@ public class WatchManager {
private PowerManager.WakeLock wakeLock;
private long lastBackgroundUpdateTime;
@Inject
public WatchManager(DatabaseManager databaseManager) {
alarmManager = (AlarmManager) getAppContext().getSystemService(Context.ALARM_SERVICE);
powerManager = (PowerManager) getAppContext().getSystemService(Context.POWER_SERVICE);

@ -21,7 +21,6 @@ import android.text.SpannableString;
import android.text.TextUtils;
import org.floens.chan.chan.ChanParser;
import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.settings.ChanSettings;
import org.jsoup.parser.Parser;
@ -32,6 +31,8 @@ import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.floens.chan.Chan.getGraph;
/**
* Contains all data needed to represent a single post.<br>
* Call {@link #finish()} to parse the comment etc. The post data is invalid if finish returns false.<br>
@ -175,7 +176,8 @@ public class Post {
spoiler = false;
}
ChanParser.getInstance().parse(this);
ChanParser chanParser = getGraph().getChanParser();
chanParser.parse(this);
repliesTo = Collections.unmodifiableSet(repliesTo);

@ -22,7 +22,6 @@ import android.util.JsonReader;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import org.floens.chan.Chan;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.database.DatabaseSavedReplyManager;
import org.floens.chan.core.manager.FilterEngine;
@ -41,9 +40,11 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import static org.floens.chan.Chan.getGraph;
/**
* Process a typical imageboard json response.<br>
* This class is highly multithreaded, take good care to don't access models that are to be only
* This class is highly multithreaded, take good care to not access models that are to be only
* changed on the main thread.
*/
public class ChanReaderRequest extends JsonReaderRequest<ChanReaderRequest.ChanReaderResponse> {
@ -58,11 +59,12 @@ public class ChanReaderRequest extends JsonReaderRequest<ChanReaderRequest.ChanR
EXECUTOR = Executors.newFixedThreadPool(THREAD_COUNT);
}
DatabaseManager databaseManager;
private Loadable loadable;
private List<Post> cached;
private Post op;
private FilterEngine filterEngine;
private DatabaseManager databaseManager;
private DatabaseSavedReplyManager databaseSavedReplyManager;
private List<Filter> filters;
@ -70,8 +72,10 @@ public class ChanReaderRequest extends JsonReaderRequest<ChanReaderRequest.ChanR
private ChanReaderRequest(String url, Listener<ChanReaderResponse> listener, ErrorListener errorListener) {
super(url, listener, errorListener);
getGraph().inject(this);
filterEngine = FilterEngine.getInstance();
databaseManager = Chan.getDatabaseManager();
databaseSavedReplyManager = databaseManager.getDatabaseSavedReplyManager();
}

@ -19,7 +19,6 @@ package org.floens.chan.core.presenter;
import android.text.TextUtils;
import org.floens.chan.Chan;
import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.database.DatabaseManager;
@ -43,6 +42,9 @@ import java.nio.charset.Charset;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import static org.floens.chan.Chan.getGraph;
import static org.floens.chan.utils.AndroidUtils.getReadableFileSize;
import static org.floens.chan.utils.AndroidUtils.getRes;
import static org.floens.chan.utils.AndroidUtils.getString;
@ -59,10 +61,17 @@ public class ReplyPresenter implements ReplyManager.HttpCallback<ReplyHttpCall>,
private ReplyPresenterCallback callback;
private ReplyManager replyManager;
private BoardManager boardManager;
private WatchManager watchManager;
private DatabaseManager databaseManager;
@Inject
ReplyManager replyManager;
@Inject
BoardManager boardManager;
@Inject
WatchManager watchManager;
@Inject
DatabaseManager databaseManager;
private boolean bound = false;
private Loadable loadable;
@ -78,10 +87,7 @@ public class ReplyPresenter implements ReplyManager.HttpCallback<ReplyHttpCall>,
public ReplyPresenter(ReplyPresenterCallback callback) {
this.callback = callback;
replyManager = Chan.getReplyManager();
boardManager = Chan.getBoardManager();
watchManager = Chan.getWatchManager();
databaseManager = Chan.getDatabaseManager();
getGraph().inject(this);
}
public void bindLoadable(Loadable loadable) {

@ -24,7 +24,6 @@ import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import org.floens.chan.Chan;
import org.floens.chan.R;
import org.floens.chan.controller.Controller;
import org.floens.chan.core.database.DatabaseManager;
@ -32,13 +31,17 @@ import org.floens.chan.core.model.SavedReply;
import java.util.Random;
import javax.inject.Inject;
import static org.floens.chan.Chan.getGraph;
import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AndroidUtils.getAttrColor;
public class DeveloperSettingsController extends Controller {
private TextView summaryText;
private DatabaseManager databaseManager;
@Inject
DatabaseManager databaseManager;
public DeveloperSettingsController(Context context) {
super(context);
@ -48,7 +51,7 @@ public class DeveloperSettingsController extends Controller {
public void onCreate() {
super.onCreate();
databaseManager = Chan.getDatabaseManager();
getGraph().inject(this);
navigationItem.setTitle(R.string.settings_developer);
@ -77,7 +80,7 @@ public class DeveloperSettingsController extends Controller {
resetDbButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Chan.getDatabaseManager().reset();
databaseManager.reset();
System.exit(0);
}
});
@ -111,7 +114,7 @@ public class DeveloperSettingsController extends Controller {
private void setDbSummary() {
String dbSummary = "";
dbSummary += "Database summary:\n";
dbSummary += Chan.getDatabaseManager().getSummary();
dbSummary += databaseManager.getSummary();
summaryText.setText(dbSummary);
}
}

@ -30,6 +30,7 @@ import android.widget.Toast;
import org.floens.chan.Chan;
import org.floens.chan.R;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.manager.BoardManager;
import org.floens.chan.core.model.Board;
import org.floens.chan.core.settings.ChanSettings;
@ -53,8 +54,11 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.inject.Inject;
import de.greenrobot.event.EventBus;
import static org.floens.chan.Chan.getGraph;
import static org.floens.chan.ui.theme.ThemeHelper.theme;
import static org.floens.chan.utils.AndroidUtils.getString;
@ -80,6 +84,9 @@ public class MainSettingsController extends SettingsController implements Toolba
private PopupWindow advancedSettingsHint;
@Inject
DatabaseManager databaseManager;
public MainSettingsController(Context context) {
super(context);
}
@ -88,6 +95,7 @@ public class MainSettingsController extends SettingsController implements Toolba
public void onCreate() {
super.onCreate();
getGraph().inject(this);
EventBus.getDefault().register(this);
navigationItem.setTitle(R.string.settings_screen);

@ -37,7 +37,6 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import org.floens.chan.R;
import org.floens.chan.chan.ChanParser;
import org.floens.chan.controller.Controller;
import org.floens.chan.core.model.Board;
import org.floens.chan.core.model.Loadable;
@ -61,6 +60,7 @@ import org.floens.chan.utils.Time;
import java.util.ArrayList;
import java.util.List;
import static org.floens.chan.Chan.getGraph;
import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AndroidUtils.getAttrColor;
import static org.floens.chan.utils.AndroidUtils.getString;
@ -251,7 +251,7 @@ public class ThemeSettingsController extends Controller implements View.OnClickL
"http://example.com/" +
"<br>" +
"Phasellus consequat semper sodales. Donec dolor lectus, aliquet nec mollis vel, rutrum vel enim.";
ChanParser.getInstance().parse(theme, post);
getGraph().getChanParser().parse(theme, post);
LinearLayout linearLayout = new LinearLayout(themeContext);
linearLayout.setOrientation(LinearLayout.VERTICAL);

@ -40,7 +40,6 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.floens.chan.Chan;
import org.floens.chan.R;
import org.floens.chan.controller.Controller;
import org.floens.chan.core.database.DatabaseManager;
@ -63,6 +62,9 @@ import org.floens.chan.utils.AndroidUtils;
import java.util.List;
import javax.inject.Inject;
import static org.floens.chan.Chan.getGraph;
import static org.floens.chan.ui.theme.ThemeHelper.theme;
import static org.floens.chan.utils.AndroidUtils.fixSnackbarText;
import static org.floens.chan.utils.AndroidUtils.getString;
@ -77,7 +79,8 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
ERROR;
}
private DatabaseManager databaseManager;
@Inject
DatabaseManager databaseManager;
private ThreadLayoutCallback callback;
@ -528,7 +531,7 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T
}
private void init() {
databaseManager = Chan.getDatabaseManager();
getGraph().inject(this);
}
@Override

@ -4,7 +4,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.android.tools.build:gradle:2.2.3'
}
}

Loading…
Cancel
Save