After Width: | Height: | Size: 344 B |
@ -0,0 +1,29 @@ |
|||||||
|
/* |
||||||
|
* 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; |
||||||
|
|
||||||
|
|
||||||
|
public class DatabaseSiteManager { |
||||||
|
private DatabaseManager databaseManager; |
||||||
|
private DatabaseHelper databaseHelper; |
||||||
|
|
||||||
|
public DatabaseSiteManager(DatabaseManager databaseManager, DatabaseHelper databaseHelper) { |
||||||
|
this.databaseManager = databaseManager; |
||||||
|
this.databaseHelper = databaseHelper; |
||||||
|
} |
||||||
|
} |
@ -1,131 +0,0 @@ |
|||||||
package org.floens.chan.core.di; |
|
||||||
|
|
||||||
import com.android.volley.RequestQueue; |
|
||||||
import com.android.volley.toolbox.ImageLoader; |
|
||||||
|
|
||||||
import org.floens.chan.Chan; |
|
||||||
import org.floens.chan.chan.ChanLoader; |
|
||||||
import org.floens.chan.chan.ChanParser; |
|
||||||
import org.floens.chan.core.cache.FileCache; |
|
||||||
import org.floens.chan.core.database.DatabaseManager; |
|
||||||
import org.floens.chan.core.manager.BoardManager; |
|
||||||
import org.floens.chan.core.manager.FilterEngine; |
|
||||||
import org.floens.chan.core.manager.ReplyManager; |
|
||||||
import org.floens.chan.core.manager.WatchManager; |
|
||||||
import org.floens.chan.core.presenter.ImageViewerPresenter; |
|
||||||
import org.floens.chan.core.presenter.ReplyPresenter; |
|
||||||
import org.floens.chan.core.presenter.ThreadPresenter; |
|
||||||
import org.floens.chan.core.receiver.WatchUpdateReceiver; |
|
||||||
import org.floens.chan.core.saver.ImageSaveTask; |
|
||||||
import org.floens.chan.core.site.http.HttpCallManager; |
|
||||||
import org.floens.chan.core.site.sites.chan4.Chan4; |
|
||||||
import org.floens.chan.core.site.sites.chan4.Chan4ReaderRequest; |
|
||||||
import org.floens.chan.core.update.UpdateManager; |
|
||||||
import org.floens.chan.ui.activity.StartActivity; |
|
||||||
import org.floens.chan.ui.adapter.DrawerAdapter; |
|
||||||
import org.floens.chan.ui.adapter.PostsFilter; |
|
||||||
import org.floens.chan.ui.controller.BoardEditController; |
|
||||||
import org.floens.chan.ui.controller.BrowseController; |
|
||||||
import org.floens.chan.ui.controller.DeveloperSettingsController; |
|
||||||
import org.floens.chan.ui.controller.DrawerController; |
|
||||||
import org.floens.chan.ui.controller.FiltersController; |
|
||||||
import org.floens.chan.ui.controller.HistoryController; |
|
||||||
import org.floens.chan.ui.controller.ImageViewerController; |
|
||||||
import org.floens.chan.ui.controller.MainSettingsController; |
|
||||||
import org.floens.chan.ui.controller.PassSettingsController; |
|
||||||
import org.floens.chan.ui.controller.ViewThreadController; |
|
||||||
import org.floens.chan.ui.helper.ImagePickDelegate; |
|
||||||
import org.floens.chan.ui.layout.FilterLayout; |
|
||||||
import org.floens.chan.ui.layout.ThreadLayout; |
|
||||||
import org.floens.chan.ui.service.WatchNotifier; |
|
||||||
import org.floens.chan.ui.view.MultiImageView; |
|
||||||
|
|
||||||
import javax.inject.Singleton; |
|
||||||
|
|
||||||
import dagger.Component; |
|
||||||
|
|
||||||
@Component(modules = { |
|
||||||
AppModule.class, |
|
||||||
NetModule.class |
|
||||||
}) |
|
||||||
@Singleton |
|
||||||
/** |
|
||||||
* Note: please avoid adding inject() statements for Sites. |
|
||||||
*/ |
|
||||||
public interface ChanGraph { |
|
||||||
ChanParser getChanParser(); |
|
||||||
|
|
||||||
BoardManager getBoardManager(); |
|
||||||
|
|
||||||
DatabaseManager getDatabaseManager(); |
|
||||||
|
|
||||||
ReplyManager getReplyManager(); |
|
||||||
|
|
||||||
RequestQueue getRequestQueue(); |
|
||||||
|
|
||||||
ImageLoader getImageLoader(); |
|
||||||
|
|
||||||
FileCache getFileCache(); |
|
||||||
|
|
||||||
HttpCallManager getHttpCallManager(); |
|
||||||
|
|
||||||
void inject(Chan chan); |
|
||||||
|
|
||||||
void inject(MainSettingsController mainSettingsController); |
|
||||||
|
|
||||||
void inject(ReplyPresenter replyPresenter); |
|
||||||
|
|
||||||
void inject(Chan4ReaderRequest chanReaderRequest); |
|
||||||
|
|
||||||
void inject(ThreadLayout threadLayout); |
|
||||||
|
|
||||||
void inject(DeveloperSettingsController developerSettingsController); |
|
||||||
|
|
||||||
void inject(StartActivity startActivity); |
|
||||||
|
|
||||||
void inject(ThreadPresenter threadPresenter); |
|
||||||
|
|
||||||
void inject(BoardEditController boardEditController); |
|
||||||
|
|
||||||
void inject(FilterEngine filterEngine); |
|
||||||
|
|
||||||
void inject(BrowseController browseController); |
|
||||||
|
|
||||||
void inject(FilterLayout filterLayout); |
|
||||||
|
|
||||||
void inject(HistoryController historyController); |
|
||||||
|
|
||||||
void inject(DrawerController drawerController); |
|
||||||
|
|
||||||
void inject(DrawerAdapter drawerAdapter); |
|
||||||
|
|
||||||
void inject(WatchNotifier watchNotifier); |
|
||||||
|
|
||||||
void inject(WatchUpdateReceiver watchUpdateReceiver); |
|
||||||
|
|
||||||
void inject(ImagePickDelegate imagePickDelegate); |
|
||||||
|
|
||||||
void inject(PassSettingsController passSettingsController); |
|
||||||
|
|
||||||
void inject(FiltersController filtersController); |
|
||||||
|
|
||||||
void inject(PostsFilter postsFilter); |
|
||||||
|
|
||||||
void inject(ChanLoader chanLoader); |
|
||||||
|
|
||||||
void inject(ImageViewerController imageViewerController); |
|
||||||
|
|
||||||
void inject(ImageViewerPresenter imageViewerPresenter); |
|
||||||
|
|
||||||
void inject(MultiImageView multiImageView); |
|
||||||
|
|
||||||
void inject(ImageSaveTask imageSaveTask); |
|
||||||
|
|
||||||
void inject(ViewThreadController viewThreadController); |
|
||||||
|
|
||||||
void inject(WatchManager.PinWatcher pinWatcher); |
|
||||||
|
|
||||||
void inject(UpdateManager updateManager); |
|
||||||
|
|
||||||
void inject(Chan4 chan4); |
|
||||||
} |
|
@ -0,0 +1,29 @@ |
|||||||
|
/* |
||||||
|
* 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.manager; |
||||||
|
|
||||||
|
|
||||||
|
import javax.inject.Inject; |
||||||
|
import javax.inject.Singleton; |
||||||
|
|
||||||
|
@Singleton |
||||||
|
public class SiteManager { |
||||||
|
@Inject |
||||||
|
public SiteManager() { |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,37 @@ |
|||||||
|
/* |
||||||
|
* 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.model; |
||||||
|
|
||||||
|
import com.j256.ormlite.field.DatabaseField; |
||||||
|
import com.j256.ormlite.table.DatabaseTable; |
||||||
|
|
||||||
|
/** |
||||||
|
* Only for storing what sites we know of, for hardcoded sites the sites we have enabled, |
||||||
|
* and for dynamic sites all settings for it. |
||||||
|
*/ |
||||||
|
@DatabaseTable |
||||||
|
public class SiteModel { |
||||||
|
@DatabaseField(id = true, unique = true) |
||||||
|
public int id; |
||||||
|
|
||||||
|
@DatabaseField |
||||||
|
public String name; |
||||||
|
|
||||||
|
@DatabaseField |
||||||
|
public String options; |
||||||
|
} |
@ -0,0 +1,120 @@ |
|||||||
|
/* |
||||||
|
* 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.presenter; |
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.BitmapFactory; |
||||||
|
import android.graphics.drawable.BitmapDrawable; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
|
||||||
|
import org.floens.chan.utils.AndroidUtils; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.floens.chan.utils.AndroidUtils.getAppContext; |
||||||
|
import static org.floens.chan.utils.AndroidUtils.getRes; |
||||||
|
|
||||||
|
public class SetupPresenter { |
||||||
|
private Callback callback; |
||||||
|
|
||||||
|
private List<AddedSite> sites = new ArrayList<>(); |
||||||
|
|
||||||
|
public void create(Callback callback) { |
||||||
|
this.callback = callback; |
||||||
|
|
||||||
|
this.callback.setAddedSites(sites); |
||||||
|
|
||||||
|
this.callback.setNextAllowed(!sites.isEmpty(), false); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean mayExit() { |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public void onUrlSubmitClicked(String url) { |
||||||
|
callback.goToUrlSubmittedState(); |
||||||
|
|
||||||
|
AndroidUtils.runOnUiThread(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
siteAdded(getTestSite()); |
||||||
|
} |
||||||
|
}, 500); |
||||||
|
// callback.showUrlHint("foo bar baz");
|
||||||
|
} |
||||||
|
|
||||||
|
public void onNextClicked() { |
||||||
|
if (!sites.isEmpty()) { |
||||||
|
callback.moveToSavedBoards(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void siteAdded(AddedSite site) { |
||||||
|
sites.add(site); |
||||||
|
callback.setAddedSites(sites); |
||||||
|
callback.runSiteAddedAnimation(site); |
||||||
|
|
||||||
|
callback.setNextAllowed(!sites.isEmpty(), true); |
||||||
|
} |
||||||
|
|
||||||
|
private int counter; |
||||||
|
|
||||||
|
private AddedSite getTestSite() { |
||||||
|
AddedSite site = new AddedSite(); |
||||||
|
site.id = counter++; |
||||||
|
site.title = "4chan.org"; |
||||||
|
|
||||||
|
Bitmap bitmap; |
||||||
|
try { |
||||||
|
BitmapFactory.Options opts = new BitmapFactory.Options(); |
||||||
|
opts.inScaled = false; |
||||||
|
bitmap = BitmapFactory.decodeStream(getAppContext().getAssets().open("icons/4chan.png"), null, opts); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
|
||||||
|
BitmapDrawable drawable = new BitmapDrawable(getRes(), bitmap); |
||||||
|
drawable = (BitmapDrawable) drawable.mutate(); |
||||||
|
drawable.getPaint().setFilterBitmap(false); |
||||||
|
site.drawable = drawable; |
||||||
|
return site; |
||||||
|
} |
||||||
|
|
||||||
|
public interface Callback { |
||||||
|
void goToUrlSubmittedState(); |
||||||
|
|
||||||
|
void runSiteAddedAnimation(AddedSite site); |
||||||
|
|
||||||
|
void setAddedSites(List<AddedSite> sites); |
||||||
|
|
||||||
|
void setNextAllowed(boolean nextAllowed, boolean animate); |
||||||
|
|
||||||
|
void showUrlHint(String text); |
||||||
|
|
||||||
|
void moveToSavedBoards(); |
||||||
|
} |
||||||
|
|
||||||
|
public static class AddedSite { |
||||||
|
public int id; |
||||||
|
public String title; |
||||||
|
public Drawable drawable; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
/* |
||||||
|
* 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.site; |
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.BitmapFactory; |
||||||
|
import android.graphics.drawable.BitmapDrawable; |
||||||
|
import android.graphics.drawable.Drawable; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
import okhttp3.HttpUrl; |
||||||
|
|
||||||
|
import static org.floens.chan.utils.AndroidUtils.getAppContext; |
||||||
|
import static org.floens.chan.utils.AndroidUtils.getRes; |
||||||
|
|
||||||
|
public class SiteIcon { |
||||||
|
private String assetPath; |
||||||
|
private HttpUrl url; |
||||||
|
|
||||||
|
public static SiteIcon fromAssets(String path) { |
||||||
|
SiteIcon siteIcon = new SiteIcon(); |
||||||
|
siteIcon.assetPath = path; |
||||||
|
return siteIcon; |
||||||
|
} |
||||||
|
|
||||||
|
public static SiteIcon fromUrl(HttpUrl url) { |
||||||
|
SiteIcon siteIcon = new SiteIcon(); |
||||||
|
siteIcon.url = url; |
||||||
|
return siteIcon; |
||||||
|
} |
||||||
|
|
||||||
|
public void get(SiteIconResult result) { |
||||||
|
if (assetPath != null) { |
||||||
|
Bitmap bitmap; |
||||||
|
try { |
||||||
|
BitmapFactory.Options opts = new BitmapFactory.Options(); |
||||||
|
opts.inScaled = false; |
||||||
|
bitmap = BitmapFactory.decodeStream(getAppContext().getAssets().open(assetPath), null, opts); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
|
||||||
|
BitmapDrawable drawable = new BitmapDrawable(getRes(), bitmap); |
||||||
|
drawable = (BitmapDrawable) drawable.mutate(); |
||||||
|
drawable.getPaint().setFilterBitmap(false); |
||||||
|
result.onSiteIcon(this, drawable); |
||||||
|
} else if (url != null) { |
||||||
|
// TODO
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public interface SiteIconResult { |
||||||
|
void onSiteIcon(SiteIcon siteIcon, Drawable icon); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,178 @@ |
|||||||
|
/* |
||||||
|
* 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.ui.controller; |
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.BitmapFactory; |
||||||
|
import android.graphics.drawable.BitmapDrawable; |
||||||
|
import android.support.v7.widget.LinearLayoutManager; |
||||||
|
import android.support.v7.widget.RecyclerView; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.widget.ArrayAdapter; |
||||||
|
import android.widget.AutoCompleteTextView; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import org.floens.chan.R; |
||||||
|
import org.floens.chan.controller.Controller; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.floens.chan.utils.AndroidUtils.getAppContext; |
||||||
|
import static org.floens.chan.utils.AndroidUtils.getRes; |
||||||
|
|
||||||
|
public class BoardSetupController extends Controller implements View.OnClickListener { |
||||||
|
private AutoCompleteTextView code; |
||||||
|
private RecyclerView savedBoardsRecycler; |
||||||
|
|
||||||
|
private SavedBoardsAdapter adapter; |
||||||
|
|
||||||
|
public BoardSetupController(Context context) { |
||||||
|
super(context); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onCreate() { |
||||||
|
super.onCreate(); |
||||||
|
|
||||||
|
view = inflateRes(R.layout.controller_board_setup); |
||||||
|
navigationItem.setTitle(R.string.saved_boards_title); |
||||||
|
|
||||||
|
code = (AutoCompleteTextView) view.findViewById(R.id.code); |
||||||
|
savedBoardsRecycler = (RecyclerView) view.findViewById(R.id.boards_recycler); |
||||||
|
savedBoardsRecycler.setLayoutManager(new LinearLayoutManager(context)); |
||||||
|
|
||||||
|
adapter = new SavedBoardsAdapter(); |
||||||
|
savedBoardsRecycler.setAdapter(adapter); |
||||||
|
|
||||||
|
List<SavedBoard> savedBoards = new ArrayList<>(); |
||||||
|
for (int board = 0; board < 5; board++) { |
||||||
|
savedBoards.add(new SavedBoard("foo - " + board, board)); |
||||||
|
} |
||||||
|
|
||||||
|
adapter.setSavedBoards(savedBoards); |
||||||
|
|
||||||
|
List<String> foo = new ArrayList<String>() {{ |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("foo"); |
||||||
|
add("bar"); |
||||||
|
add("baz"); |
||||||
|
}}; |
||||||
|
|
||||||
|
ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_dropdown_item_1line, foo); |
||||||
|
code.setAdapter(adapter); |
||||||
|
code.setThreshold(1); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
} |
||||||
|
|
||||||
|
private class SavedBoard { |
||||||
|
private String title; |
||||||
|
private int id; |
||||||
|
|
||||||
|
public SavedBoard(String title, int id) { |
||||||
|
this.title = title; |
||||||
|
this.id = id; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class SavedBoardsAdapter extends RecyclerView.Adapter<SavedBoardCell> { |
||||||
|
private List<SavedBoard> savedBoards = new ArrayList<>(); |
||||||
|
|
||||||
|
public SavedBoardsAdapter() { |
||||||
|
setHasStableIds(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void setSavedBoards(List<SavedBoard> savedBoards) { |
||||||
|
this.savedBoards.clear(); |
||||||
|
this.savedBoards.addAll(savedBoards); |
||||||
|
notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getItemId(int position) { |
||||||
|
return savedBoards.get(position).id; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SavedBoardCell onCreateViewHolder(ViewGroup parent, int viewType) { |
||||||
|
return new SavedBoardCell(LayoutInflater.from(context).inflate(R.layout.cell_saved_board, parent, false)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(SavedBoardCell holder, int position) { |
||||||
|
SavedBoard savedBoard = savedBoards.get(position); |
||||||
|
holder.setSavedBoard(savedBoard); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return savedBoards.size(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class SavedBoardCell extends RecyclerView.ViewHolder { |
||||||
|
private ImageView image; |
||||||
|
private TextView text; |
||||||
|
|
||||||
|
public SavedBoardCell(View itemView) { |
||||||
|
super(itemView); |
||||||
|
|
||||||
|
image = (ImageView) itemView.findViewById(R.id.image); |
||||||
|
text = (TextView) itemView.findViewById(R.id.text); |
||||||
|
} |
||||||
|
|
||||||
|
public void setSavedBoard(SavedBoard savedBoard) { |
||||||
|
Bitmap bitmap; |
||||||
|
try { |
||||||
|
BitmapFactory.Options opts = new BitmapFactory.Options(); |
||||||
|
opts.inScaled = false; |
||||||
|
bitmap = BitmapFactory.decodeStream(getAppContext().getAssets().open("icons/4chan.png"), null, opts); |
||||||
|
} catch (IOException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
|
||||||
|
BitmapDrawable drawable = new BitmapDrawable(getRes(), bitmap); |
||||||
|
drawable = (BitmapDrawable) drawable.mutate(); |
||||||
|
drawable.getPaint().setFilterBitmap(false); |
||||||
|
|
||||||
|
image.setImageDrawable(drawable); |
||||||
|
text.setText(savedBoard.title); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,357 @@ |
|||||||
|
/* |
||||||
|
* 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.ui.controller; |
||||||
|
|
||||||
|
|
||||||
|
import android.animation.Animator; |
||||||
|
import android.animation.AnimatorListenerAdapter; |
||||||
|
import android.animation.AnimatorSet; |
||||||
|
import android.animation.ArgbEvaluator; |
||||||
|
import android.animation.ObjectAnimator; |
||||||
|
import android.animation.ValueAnimator; |
||||||
|
import android.annotation.TargetApi; |
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.graphics.Paint; |
||||||
|
import android.graphics.Path; |
||||||
|
import android.os.Build; |
||||||
|
import android.support.v4.view.animation.PathInterpolatorCompat; |
||||||
|
import android.support.v7.widget.LinearLayoutManager; |
||||||
|
import android.support.v7.widget.RecyclerView; |
||||||
|
import android.view.LayoutInflater; |
||||||
|
import android.view.View; |
||||||
|
import android.view.ViewGroup; |
||||||
|
import android.view.ViewGroupOverlay; |
||||||
|
import android.widget.Button; |
||||||
|
import android.widget.EditText; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import org.floens.chan.R; |
||||||
|
import org.floens.chan.controller.transition.FadeInTransition; |
||||||
|
import org.floens.chan.core.presenter.SetupPresenter; |
||||||
|
import org.floens.chan.ui.animation.AnimationUtils; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.floens.chan.utils.AndroidUtils.dp; |
||||||
|
import static org.floens.chan.utils.AndroidUtils.getAttrColor; |
||||||
|
|
||||||
|
public class SiteSetupController extends StyledToolbarNavigationController implements View.OnClickListener, SetupPresenter.Callback { |
||||||
|
private EditText url; |
||||||
|
private View urlSubmit; |
||||||
|
private View spinner; |
||||||
|
private Button next; |
||||||
|
|
||||||
|
private boolean blocked = false; |
||||||
|
|
||||||
|
private SetupPresenter presenter; |
||||||
|
|
||||||
|
private RecyclerView sitesRecyclerview; |
||||||
|
private SitesAdapter sitesAdapter; |
||||||
|
private List<SetupPresenter.AddedSite> sites = new ArrayList<>(); |
||||||
|
|
||||||
|
public SiteSetupController(Context context) { |
||||||
|
super(context); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onCreate() { |
||||||
|
super.onCreate(); |
||||||
|
|
||||||
|
view = inflateRes(R.layout.controller_site_setup); |
||||||
|
navigationItem.setTitle(R.string.setup_title); |
||||||
|
|
||||||
|
url = (EditText) view.findViewById(R.id.site_url); |
||||||
|
urlSubmit = view.findViewById(R.id.site_url_submit); |
||||||
|
urlSubmit.setOnClickListener(this); |
||||||
|
spinner = view.findViewById(R.id.progress); |
||||||
|
sitesRecyclerview = (RecyclerView) view.findViewById(R.id.sites_recycler); |
||||||
|
sitesRecyclerview.setLayoutManager(new LinearLayoutManager(context)); |
||||||
|
next = (Button) view.findViewById(R.id.next_button); |
||||||
|
next.setOnClickListener(this); |
||||||
|
|
||||||
|
presenter = new SetupPresenter(); |
||||||
|
|
||||||
|
sitesAdapter = new SitesAdapter(); |
||||||
|
sitesRecyclerview.setAdapter(sitesAdapter); |
||||||
|
|
||||||
|
presenter.create(this); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (blocked) return; |
||||||
|
|
||||||
|
if (v == urlSubmit) { |
||||||
|
presenter.onUrlSubmitClicked(url.getText().toString()); |
||||||
|
} else if (v == next) { |
||||||
|
presenter.onNextClicked(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean onBack() { |
||||||
|
if (presenter.mayExit()) { |
||||||
|
return super.onBack(); |
||||||
|
} else { |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void moveToSavedBoards() { |
||||||
|
navigationController.pushController(new BoardSetupController(context), new FadeInTransition()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void goToUrlSubmittedState() { |
||||||
|
spinner.setVisibility(View.VISIBLE); |
||||||
|
urlSubmit.setVisibility(View.INVISIBLE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void runSiteAddedAnimation(final SetupPresenter.AddedSite site) { |
||||||
|
spinner.setVisibility(View.INVISIBLE); |
||||||
|
urlSubmit.setVisibility(View.VISIBLE); |
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { |
||||||
|
runSiteAddedAnimationInternal(site); |
||||||
|
} else { |
||||||
|
resetUrl(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void showUrlHint(String text) { |
||||||
|
spinner.setVisibility(View.INVISIBLE); |
||||||
|
urlSubmit.setVisibility(View.VISIBLE); |
||||||
|
|
||||||
|
url.setError(text, null); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setAddedSites(List<SetupPresenter.AddedSite> sites) { |
||||||
|
this.sites.clear(); |
||||||
|
this.sites.addAll(sites); |
||||||
|
sitesAdapter.notifyDataSetChanged(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setNextAllowed(boolean nextAllowed, boolean animate) { |
||||||
|
next.setEnabled(nextAllowed); |
||||||
|
int newBackground = getAttrColor(context, nextAllowed ? R.attr.colorAccent : R.attr.backcolor); |
||||||
|
int newTextColor = nextAllowed ? Color.WHITE : getAttrColor(context, R.attr.text_color_hint); |
||||||
|
if (animate) { |
||||||
|
AnimationUtils.animateTextColor(next, newTextColor); |
||||||
|
AnimationUtils.animateBackgroundColorDrawable(next, newBackground); |
||||||
|
} else { |
||||||
|
next.setBackgroundColor(newBackground); |
||||||
|
next.setTextColor(newTextColor); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void resetUrl() { |
||||||
|
url.setText(""); |
||||||
|
} |
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) |
||||||
|
private void runSiteAddedAnimationInternal(SetupPresenter.AddedSite site) { |
||||||
|
blocked = true; |
||||||
|
sitesAdapter.invisibleSiteOnBind = site; |
||||||
|
|
||||||
|
SiteCell siteCell = new SiteCell(LayoutInflater.from(context).inflate(R.layout.cell_site, null)); |
||||||
|
siteCell.setSite(site); |
||||||
|
final View siteCellView = siteCell.itemView; |
||||||
|
final View siteCellIcon = siteCell.image; |
||||||
|
siteCellView.measure(View.MeasureSpec.makeMeasureSpec(url.getMeasuredWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); |
||||||
|
siteCellView.layout(0, 0, siteCellView.getMeasuredWidth(), siteCellView.getMeasuredHeight()); |
||||||
|
|
||||||
|
final ViewGroupOverlay overlay = view.getOverlay(); |
||||||
|
|
||||||
|
overlay.add(siteCellView); |
||||||
|
|
||||||
|
int[] urlWinLoc = new int[2]; |
||||||
|
url.getLocationInWindow(urlWinLoc); |
||||||
|
int[] recWinLoc = new int[2]; |
||||||
|
sitesRecyclerview.getLocationInWindow(recWinLoc); |
||||||
|
recWinLoc[0] += sitesRecyclerview.getPaddingLeft(); |
||||||
|
recWinLoc[1] += sitesRecyclerview.getPaddingTop() + siteCellView.getMeasuredHeight() * (sites.size() - 1); |
||||||
|
int[] viewWinLoc = new int[2]; |
||||||
|
view.getLocationInWindow(viewWinLoc); |
||||||
|
|
||||||
|
String urlText = url.getText().toString(); |
||||||
|
int indexOf = urlText.indexOf(site.title); |
||||||
|
int offsetLeft = 0; |
||||||
|
if (indexOf > 0) { |
||||||
|
Paint paint = new Paint(); |
||||||
|
paint.setTextSize(url.getTextSize()); |
||||||
|
offsetLeft = (int) paint.measureText(urlText.substring(0, indexOf)); |
||||||
|
} |
||||||
|
|
||||||
|
final int staX = urlWinLoc[0] - viewWinLoc[0] - dp(48) + dp(4) + offsetLeft; |
||||||
|
final int staY = urlWinLoc[1] - viewWinLoc[1] - dp(4); |
||||||
|
final int desX = recWinLoc[0] - viewWinLoc[0]; |
||||||
|
final int desY = recWinLoc[1] - viewWinLoc[1]; |
||||||
|
|
||||||
|
siteCellView.setTranslationX(staX); |
||||||
|
siteCellView.setTranslationY(staY); |
||||||
|
|
||||||
|
final int textColor = url.getCurrentTextColor(); |
||||||
|
final int textHintColor = url.getCurrentHintTextColor(); |
||||||
|
|
||||||
|
ValueAnimator textAlpha = ValueAnimator.ofObject(new ArgbEvaluator(), |
||||||
|
textColor, textColor & 0xffffff); |
||||||
|
textAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
url.setTextColor((int) animation.getAnimatedValue()); |
||||||
|
} |
||||||
|
}); |
||||||
|
textAlpha.setDuration(300); |
||||||
|
textAlpha.addListener(new AnimatorListenerAdapter() { |
||||||
|
@Override |
||||||
|
public void onAnimationEnd(Animator animation) { |
||||||
|
resetUrl(); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
url.setCursorVisible(false); |
||||||
|
url.setHintTextColor(0); |
||||||
|
|
||||||
|
ValueAnimator alpha = ObjectAnimator.ofFloat(siteCellView, View.ALPHA, 0f, 1f); |
||||||
|
alpha.setDuration(300); |
||||||
|
|
||||||
|
ValueAnimator iconAlpha = ValueAnimator.ofFloat(0f, 1f); |
||||||
|
iconAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
siteCellIcon.setAlpha((float) animation.getAnimatedValue()); |
||||||
|
} |
||||||
|
}); |
||||||
|
iconAlpha.setDuration(400); |
||||||
|
iconAlpha.setStartDelay(500); |
||||||
|
siteCellIcon.setAlpha(0f); |
||||||
|
|
||||||
|
ValueAnimator horizontal = ValueAnimator.ofFloat(0f, 1f); |
||||||
|
horizontal.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
float value = (float) animation.getAnimatedValue(); |
||||||
|
siteCellView.setTranslationX(staX + (desX - staX) * value); |
||||||
|
} |
||||||
|
}); |
||||||
|
horizontal.setDuration(600); |
||||||
|
horizontal.setStartDelay(400); |
||||||
|
|
||||||
|
ValueAnimator vertical = ValueAnimator.ofFloat(0f, 1f); |
||||||
|
vertical.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
float value = (float) animation.getAnimatedValue(); |
||||||
|
siteCellView.setTranslationY(staY + (desY - staY) * value); |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
Path path = new Path(); |
||||||
|
|
||||||
|
float jump = 300f / Math.abs(desY - staY); |
||||||
|
path.cubicTo(0.5f, 0f - jump, 0.75f, 1.0f, 1f, 1f); |
||||||
|
vertical.setInterpolator(PathInterpolatorCompat.create(path)); |
||||||
|
vertical.setDuration(600); |
||||||
|
vertical.setStartDelay(400); |
||||||
|
|
||||||
|
ValueAnimator hintAlpha = ValueAnimator.ofObject(new ArgbEvaluator(), |
||||||
|
textHintColor & 0xffffff, textHintColor); |
||||||
|
hintAlpha.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { |
||||||
|
@Override |
||||||
|
public void onAnimationUpdate(ValueAnimator animation) { |
||||||
|
url.setHintTextColor((int) animation.getAnimatedValue()); |
||||||
|
} |
||||||
|
}); |
||||||
|
hintAlpha.setDuration(300); |
||||||
|
hintAlpha.setStartDelay(1000); |
||||||
|
|
||||||
|
AnimatorSet set = new AnimatorSet(); |
||||||
|
set.playTogether(alpha, textAlpha, iconAlpha, horizontal, vertical, hintAlpha); |
||||||
|
set.addListener(new AnimatorListenerAdapter() { |
||||||
|
@Override |
||||||
|
public void onAnimationEnd(Animator animation) { |
||||||
|
blocked = false; |
||||||
|
overlay.remove(siteCellView); |
||||||
|
sitesAdapter.invisibleSiteOnBind = null; |
||||||
|
for (int i = 0; i < sitesRecyclerview.getChildCount(); i++) { |
||||||
|
sitesRecyclerview.getChildAt(i).setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
url.setTextColor(textColor); |
||||||
|
url.setHintTextColor(textHintColor); |
||||||
|
url.setCursorVisible(true); |
||||||
|
} |
||||||
|
}); |
||||||
|
set.start(); |
||||||
|
} |
||||||
|
|
||||||
|
private class SitesAdapter extends RecyclerView.Adapter<SiteCell> { |
||||||
|
private SetupPresenter.AddedSite invisibleSiteOnBind; |
||||||
|
|
||||||
|
public SitesAdapter() { |
||||||
|
setHasStableIds(true); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getItemId(int position) { |
||||||
|
return sites.get(position).id; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SiteCell onCreateViewHolder(ViewGroup parent, int viewType) { |
||||||
|
return new SiteCell(LayoutInflater.from(context).inflate(R.layout.cell_site, parent, false)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onBindViewHolder(SiteCell holder, int position) { |
||||||
|
SetupPresenter.AddedSite site = sites.get(position); |
||||||
|
holder.setSite(site); |
||||||
|
if (site == invisibleSiteOnBind) { |
||||||
|
holder.itemView.setVisibility(View.INVISIBLE); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public int getItemCount() { |
||||||
|
return sites.size(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private class SiteCell extends RecyclerView.ViewHolder { |
||||||
|
private ImageView image; |
||||||
|
private TextView text; |
||||||
|
|
||||||
|
public SiteCell(View itemView) { |
||||||
|
super(itemView); |
||||||
|
image = (ImageView) itemView.findViewById(R.id.image); |
||||||
|
text = (TextView) itemView.findViewById(R.id.text); |
||||||
|
} |
||||||
|
|
||||||
|
private void setSite(SetupPresenter.AddedSite site) { |
||||||
|
image.setImageDrawable(site.drawable); |
||||||
|
text.setText(site.title); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 124 B |
After Width: | Height: | Size: 147 B |
After Width: | Height: | Size: 149 B |
After Width: | Height: | Size: 151 B |
After Width: | Height: | Size: 86 B |
After Width: | Height: | Size: 114 B |
After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 125 B |
After Width: | Height: | Size: 108 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 168 B |
After Width: | Height: | Size: 114 B |
After Width: | Height: | Size: 186 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 215 B |
After Width: | Height: | Size: 119 B |
After Width: | Height: | Size: 222 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 256 B |
@ -0,0 +1,42 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
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/>. |
||||||
|
--> |
||||||
|
<LinearLayout |
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:background="?attr/backcolor" |
||||||
|
android:orientation="horizontal"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/image" |
||||||
|
android:layout_width="48dp" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:padding="8dp" |
||||||
|
android:scaleType="fitCenter"/> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/text" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:layout_weight="1" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:maxLines="1" |
||||||
|
android:textColor="?text_color_primary" |
||||||
|
android:textSize="14sp"/> |
||||||
|
|
||||||
|
</LinearLayout> |
@ -0,0 +1,41 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
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/>. |
||||||
|
--> |
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:background="?selectableItemBackground" |
||||||
|
android:orientation="horizontal"> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/image" |
||||||
|
android:layout_width="48dp" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:padding="8dp" |
||||||
|
android:scaleType="fitCenter" /> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/text" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="48dp" |
||||||
|
android:layout_weight="1" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:maxLines="1" |
||||||
|
android:textColor="?text_color_primary" |
||||||
|
android:textSize="14sp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
@ -0,0 +1,83 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
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/>. |
||||||
|
--> |
||||||
|
<android.support.constraint.ConstraintLayout |
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:background="?attr/backcolor"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/introduction" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginEnd="8dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginRight="8dp" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:text="@string/saved_boards_introduction" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toTopOf="parent"/> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/code_hint" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:gravity="center_vertical" |
||||||
|
android:text="@string/saved_boards_code" |
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/code" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introduction"/> |
||||||
|
|
||||||
|
<AutoCompleteTextView |
||||||
|
android:id="@+id/code" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginEnd="8dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginRight="8dp" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:ems="10" |
||||||
|
android:hint="@string/saved_boards_code_hint" |
||||||
|
android:inputType="textPersonName" |
||||||
|
android:textSize="14sp" |
||||||
|
app:layout_constraintHorizontal_bias="0.0" |
||||||
|
app:layout_constraintLeft_toRightOf="@+id/code_hint" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introduction"/> |
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView |
||||||
|
android:id="@+id/boards_recycler" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_marginBottom="8dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginRight="8dp" |
||||||
|
android:layout_marginTop="0dp" |
||||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/code"/> |
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout> |
@ -0,0 +1,150 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!-- |
||||||
|
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/>. |
||||||
|
--> |
||||||
|
<android.support.constraint.ConstraintLayout |
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto" |
||||||
|
xmlns:tools="http://schemas.android.com/tools" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:animateLayoutChanges="true" |
||||||
|
android:background="?attr/backcolor" |
||||||
|
tools:ignore="ContentDescription,RtlHardcoded"> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/introduction" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginEnd="8dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginRight="8dp" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:text="@string/setup_introduction" |
||||||
|
app:layout_constraintHorizontal_bias="0.0" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toTopOf="parent"/> |
||||||
|
|
||||||
|
<EditText |
||||||
|
android:id="@+id/site_url" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginEnd="8dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginRight="8dp" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:hint="@string/setup_site_url_hint" |
||||||
|
android:inputType="textUri" |
||||||
|
android:textSize="14sp" |
||||||
|
app:layout_constraintHorizontal_bias="0.0" |
||||||
|
app:layout_constraintLeft_toRightOf="@+id/site_url_label" |
||||||
|
app:layout_constraintRight_toLeftOf="@+id/site_url_submit" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introduction"/> |
||||||
|
|
||||||
|
<ImageButton |
||||||
|
android:id="@+id/site_url_submit" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_marginEnd="7dp" |
||||||
|
android:layout_marginRight="7dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:background="?selectableItemBackground" |
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/site_url" |
||||||
|
app:layout_constraintDimensionRatio="w,1:1" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introduction" |
||||||
|
app:layout_constraintVertical_bias="0.0" |
||||||
|
app:srcCompat="@drawable/ic_add_black_24dp"/> |
||||||
|
|
||||||
|
<ProgressBar |
||||||
|
android:id="@+id/progress" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_marginEnd="8dp" |
||||||
|
android:layout_marginRight="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:padding="8dp" |
||||||
|
android:visibility="invisible" |
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/site_url" |
||||||
|
app:layout_constraintDimensionRatio="w,1:1" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introduction"/> |
||||||
|
|
||||||
|
<TextView |
||||||
|
android:id="@+id/site_url_label" |
||||||
|
android:layout_width="wrap_content" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_marginBottom="0dp" |
||||||
|
android:layout_marginLeft="8dp" |
||||||
|
android:layout_marginStart="8dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:gravity="center" |
||||||
|
android:text="@string/setup_site_url" |
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/site_url" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introduction" |
||||||
|
app:layout_constraintVertical_bias="0.0"/> |
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView |
||||||
|
android:id="@+id/sites_recycler" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="0dp" |
||||||
|
android:layout_marginBottom="0dp" |
||||||
|
android:layout_marginLeft="0dp" |
||||||
|
android:layout_marginRight="0dp" |
||||||
|
android:layout_marginTop="0dp" |
||||||
|
android:padding="8dp" |
||||||
|
android:scrollbarStyle="outsideOverlay" |
||||||
|
android:scrollbars="vertical" |
||||||
|
app:layout_constraintBottom_toTopOf="@+id/next_button" |
||||||
|
app:layout_constraintHorizontal_bias="0.0" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/divider"/> |
||||||
|
|
||||||
|
<View |
||||||
|
android:id="@+id/divider" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="1dp" |
||||||
|
android:layout_marginLeft="0dp" |
||||||
|
android:layout_marginRight="0dp" |
||||||
|
android:layout_marginTop="8dp" |
||||||
|
android:background="?attr/divider_color" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintRight_toRightOf="parent" |
||||||
|
app:layout_constraintTop_toBottomOf="@+id/site_url"/> |
||||||
|
|
||||||
|
<Button |
||||||
|
android:id="@+id/next_button" |
||||||
|
style="@style/Widget.AppCompat.Button.Borderless" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="wrap_content" |
||||||
|
android:layout_marginBottom="0dp" |
||||||
|
android:layout_marginLeft="0dp" |
||||||
|
android:layout_marginRight="0dp" |
||||||
|
android:background="@android:color/white" |
||||||
|
android:elevation="12dp" |
||||||
|
android:foreground="?selectableItemBackground" |
||||||
|
android:text="@string/next" |
||||||
|
android:textColor="?text_color_hint" |
||||||
|
app:layout_constraintBottom_toBottomOf="parent" |
||||||
|
app:layout_constraintLeft_toLeftOf="parent" |
||||||
|
app:layout_constraintRight_toRightOf="parent"/> |
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout> |
@ -0,0 +1 @@ |
|||||||
|
org.gradle.jvmargs=-Xmx2048M |