diff --git a/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java b/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java index 40030ae7..4b2947d8 100644 --- a/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java +++ b/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java @@ -301,7 +301,7 @@ public class ChanLoader implements Response.ErrorListener, Response.Listener 0) { Controller top = controllerList.get(controllerList.size() - 1); if (top.onBack()) { @@ -192,48 +179,4 @@ public abstract class NavigationController extends Controller implements Toolbar controller.onConfigurationChanged(newConfig); } } - - public void onMenuClicked() { - - } - - public void showSearch() { - if (toolbar != null) { - toolbar.openSearch(); - } - } - - @Override - public void onMenuOrBackClicked(boolean isArrow) { - if (isArrow) { - onBack(); - } else { - onMenuClicked(); - } - } - - @Override - public void onSearchVisibilityChanged(boolean visible) { - } - - @Override - public String getSearchHint() { - return ""; - } - - @Override - public void onSearchEntered(String entered) { - } - - protected void updateToolbarCollapse(Controller controller, boolean animate) { - if (toolbar != null) { - if (!controller.navigationItem.collapseToolbar) { - FrameLayout.LayoutParams toViewParams = (FrameLayout.LayoutParams) controller.view.getLayoutParams(); - toViewParams.topMargin = toolbar.getToolbarHeight(); - controller.view.setLayoutParams(toViewParams); - } - - toolbar.processScrollCollapse(Toolbar.TOOLBAR_COLLAPSE_SHOW, animate); - } - } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java index 2137a965..cd7db971 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java @@ -27,6 +27,7 @@ import android.nfc.NfcAdapter; import android.nfc.NfcEvent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import android.view.LayoutInflater; import android.view.ViewGroup; import org.floens.chan.Chan; @@ -40,8 +41,9 @@ import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Pin; import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.ui.controller.BrowseController; -import org.floens.chan.ui.controller.DrawerNavigationController; +import org.floens.chan.ui.controller.DrawerController; import org.floens.chan.ui.controller.SplitNavigationController; +import org.floens.chan.ui.controller.StyledToolbarNavigationController; import org.floens.chan.ui.controller.ViewThreadController; import org.floens.chan.ui.helper.ImagePickDelegate; import org.floens.chan.ui.state.ChanState; @@ -61,7 +63,8 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat private List stack = new ArrayList<>(); private final BoardManager boardManager; - private NavigationController navigationController; + private DrawerController drawerController; + private NavigationController threadNavigationController; private BrowseController browseController; private ImagePickDelegate imagePickDelegate; @@ -80,28 +83,31 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat contentView = (ViewGroup) findViewById(android.R.id.content); - NavigationController mainThreadController; - if (AndroidUtils.isTablet(this)) { + // Setup base controllers, and decide if to use the split layout for tablets + drawerController = new DrawerController(this); + drawerController.onCreate(); + drawerController.onShow(); + + StyledToolbarNavigationController toolbarNavigationController = new StyledToolbarNavigationController(this); + + if (AndroidUtils.isTablet(this) && !ChanSettings.forcePhoneLayout.get()) { SplitNavigationController splitNavigationController = new SplitNavigationController(this); - splitNavigationController.onCreate(); - splitNavigationController.onShow(); - DrawerNavigationController leftController = new DrawerNavigationController(this); - splitNavigationController.setLeftController(leftController); + splitNavigationController.setEmptyView((ViewGroup) LayoutInflater.from(this).inflate(R.layout.layout_split_empty, null)); + + drawerController.setChildController(splitNavigationController); - navigationController = splitNavigationController; - mainThreadController = leftController; + splitNavigationController.setLeftController(toolbarNavigationController); + threadNavigationController = toolbarNavigationController; } else { - navigationController = new DrawerNavigationController(this); - navigationController.onCreate(); - mainThreadController = navigationController; + drawerController.setChildController(toolbarNavigationController); + threadNavigationController = toolbarNavigationController; } - setContentView(navigationController.view); - addController(navigationController); - browseController = new BrowseController(this); - mainThreadController.pushController(browseController, false); - mainThreadController.onShow(); + toolbarNavigationController.pushController(browseController, false); + + setContentView(drawerController.view); + addController(drawerController); // Prevent overdraw // Do this after setContentView, or the decor creating will reset the background to a default non-null drawable @@ -171,9 +177,9 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat // Handle WatchNotifier clicks if (intent.getExtras() != null) { int pinId = intent.getExtras().getInt("pin_id", -2); - if (pinId != -2 && navigationController.getTop() instanceof BrowseController) { + if (pinId != -2 && threadNavigationController.getTop() instanceof BrowseController) { if (pinId == -1) { - navigationController.onMenuClicked(); + drawerController.onMenuClicked(); } else { Pin pin = Chan.getWatchManager().findPinById(pinId); if (pin != null) { @@ -193,7 +199,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat Logger.w(TAG, "Can not save instance state, the board loadable is null"); } else { Loadable thread = null; - List controllers = navigationController.getControllerList(); + List controllers = threadNavigationController.getControllerList(); for (Controller controller : controllers) { if (controller instanceof ViewThreadController) { thread = ((ViewThreadController) controller).getLoadable(); @@ -212,7 +218,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat @Override public NdefMessage createNdefMessage(NfcEvent event) { - Controller controller = navigationController.getTop(); + Controller controller = threadNavigationController.getTop(); if (controller instanceof NfcAdapter.CreateNdefMessageCallback) { return ((NfcAdapter.CreateNdefMessageCallback) controller).createNdefMessage(event); } else { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinAdapter.java b/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinAdapter.java index f895fb42..31b5db65 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinAdapter.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/adapter/PinAdapter.java @@ -53,12 +53,17 @@ public class PinAdapter extends RecyclerView.Adapter im private final Callback callback; private List pins = new ArrayList<>(); + private Pin highlighted; public PinAdapter(Callback callback) { this.callback = callback; setHasStableIds(true); } + public void setPinHighlighted(Pin highlighted) { + this.highlighted = highlighted; + } + @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { @@ -242,7 +247,7 @@ public class PinAdapter extends RecyclerView.Adapter im dp(16), holder.textView.getPaddingBottom()); } - boolean highlighted = callback.isHighlighted(pin); + boolean highlighted = pin == this.highlighted; if (highlighted && !holder.highlighted) { holder.itemView.setBackgroundColor(0x22000000); holder.highlighted = true; @@ -377,8 +382,6 @@ public class PinAdapter extends RecyclerView.Adapter im void onHeaderClicked(HeaderHolder holder); - boolean isHighlighted(Pin pin); - void onPinRemoved(Pin pin); void onPinLongClocked(Pin pin); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java index d0d5fedf..57c80efd 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/AdvancedSettingsController.java @@ -25,10 +25,12 @@ import android.widget.LinearLayout; import org.floens.chan.R; import org.floens.chan.core.settings.ChanSettings; +import org.floens.chan.ui.activity.StartActivity; import org.floens.chan.ui.fragment.FolderPickFragment; import org.floens.chan.ui.settings.BooleanSettingView; import org.floens.chan.ui.settings.IntegerSettingView; import org.floens.chan.ui.settings.LinkSettingView; +import org.floens.chan.ui.settings.SettingView; import org.floens.chan.ui.settings.SettingsController; import org.floens.chan.ui.settings.SettingsGroup; import org.floens.chan.ui.settings.StringSettingView; @@ -39,6 +41,8 @@ public class AdvancedSettingsController extends SettingsController { private static final String TAG = "AdvancedSettingsController"; private LinkSettingView saveLocation; + private SettingView forcePhoneLayoutSetting; + private boolean needRestart; public AdvancedSettingsController(Context context) { super(context); @@ -58,6 +62,24 @@ public class AdvancedSettingsController extends SettingsController { buildPreferences(); } + @Override + public void onDestroy() { + super.onDestroy(); + + if (needRestart) { + ((StartActivity) context).restart(); + } + } + + @Override + public void onPreferenceChange(SettingView item) { + super.onPreferenceChange(item); + + if (item == forcePhoneLayoutSetting) { + needRestart = true; + } + } + private void populatePreferences() { SettingsGroup settings = new SettingsGroup(string(R.string.settings_group_advanced)); @@ -86,7 +108,7 @@ public class AdvancedSettingsController extends SettingsController { settings.add(new BooleanSettingView(this, ChanSettings.saveOriginalFilename, string(R.string.setting_save_original_filename), null)); settings.add(new BooleanSettingView(this, ChanSettings.shareUrl, string(R.string.setting_share_url), string(R.string.setting_share_url_description))); settings.add(new BooleanSettingView(this, ChanSettings.networkHttps, string(R.string.setting_network_https), string(R.string.setting_network_https_description))); - settings.add(new BooleanSettingView(this, ChanSettings.forcePhoneLayout, string(R.string.setting_force_phone_layout), null)); + forcePhoneLayoutSetting = settings.add(new BooleanSettingView(this, ChanSettings.forcePhoneLayout, string(R.string.setting_force_phone_layout), null)); settings.add(new BooleanSettingView(this, ChanSettings.anonymize, string(R.string.setting_anonymize), null)); settings.add(new BooleanSettingView(this, ChanSettings.anonymizeIds, string(R.string.setting_anonymize_ids), null)); settings.add(new BooleanSettingView(this, ChanSettings.repliesButtonsBottom, string(R.string.setting_buttons_bottom), null)); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java index 085e5349..b9e5bcc5 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/BrowseController.java @@ -29,7 +29,6 @@ import android.widget.TextView; import org.floens.chan.Chan; import org.floens.chan.R; import org.floens.chan.chan.ChanUrls; -import org.floens.chan.controller.Controller; import org.floens.chan.core.manager.BoardManager; import org.floens.chan.core.model.Board; import org.floens.chan.core.model.Loadable; @@ -117,7 +116,7 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte Integer id = (Integer) item.getId(); switch (id) { case SEARCH_ID: - navigationController.showSearch(); + ((ToolbarNavigationController) navigationController).showSearch(); break; case SHARE_ID: case OPEN_BROWSER_ID: @@ -200,7 +199,7 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte if (menu == navigationItem.middleMenu) { if (item instanceof FloatingMenuItemBoard) { loadBoard(((FloatingMenuItemBoard) item).board); - navigationController.getToolbar().updateNavigation(); + ((ToolbarNavigationController) navigationController).getToolbar().updateNavigation(); } else { navigationController.pushController(new BoardEditController(context)); menu.dismiss(); @@ -212,6 +211,11 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte public void onFloatingMenuDismissed(FloatingMenu menu) { } + @Override + public void openPin(Pin pin) { + showThread(pin.loadable); + } + @Override public void showThread(Loadable threadLoadable) { showThread(threadLoadable, true); @@ -221,13 +225,18 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte if (navigationController.navigationController instanceof SplitNavigationController) { SplitNavigationController splitNavigationController = (SplitNavigationController) navigationController.navigationController; - Controller controller = splitNavigationController.rightController; - if (controller instanceof ViewThreadController) { - ((ViewThreadController) controller).loadLoadable(threadLoadable); + if (splitNavigationController.rightController instanceof StyledToolbarNavigationController) { + StyledToolbarNavigationController navigationController = (StyledToolbarNavigationController) splitNavigationController.rightController; + + if (navigationController.getTop() instanceof ViewThreadController) { + ((ViewThreadController) navigationController.getTop()).loadThread(threadLoadable); + } } else { + StyledToolbarNavigationController navigationController = new StyledToolbarNavigationController(context); + splitNavigationController.setRightController(navigationController); ViewThreadController viewThreadController = new ViewThreadController(context); viewThreadController.setLoadable(threadLoadable); - splitNavigationController.setRightController(viewThreadController); + navigationController.pushController(viewThreadController, false); } } else { ViewThreadController viewThreadController = new ViewThreadController(context); @@ -240,16 +249,6 @@ public class BrowseController extends ThreadController implements ToolbarMenuIte loadBoards(); } - @Override - public void onPinClicked(Pin pin) { - showThread(pin.loadable); - } - - @Override - public boolean isPinCurrent(Pin pin) { - return false; - } - public void loadBoard(Board board) { Loadable loadable = new Loadable(board.value); loadable.mode = Loadable.Mode.CATALOG; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java similarity index 72% rename from Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerNavigationController.java rename to Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java index 1a8853a1..ebae34d9 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerNavigationController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/DrawerController.java @@ -27,8 +27,8 @@ import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.Gravity; import android.view.View; -import android.view.ViewGroup; import android.widget.EditText; +import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -36,14 +36,12 @@ import android.widget.TextView; import org.floens.chan.Chan; import org.floens.chan.R; import org.floens.chan.controller.Controller; -import org.floens.chan.controller.ControllerTransition; +import org.floens.chan.controller.ControllerLogic; import org.floens.chan.controller.NavigationController; import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.model.Pin; import org.floens.chan.ui.adapter.PinAdapter; import org.floens.chan.ui.helper.SwipeListener; -import org.floens.chan.ui.theme.ThemeHelper; -import org.floens.chan.ui.toolbar.Toolbar; import org.floens.chan.utils.AndroidUtils; import java.util.List; @@ -55,16 +53,19 @@ import static org.floens.chan.utils.AndroidUtils.ROBOTO_MEDIUM; import static org.floens.chan.utils.AndroidUtils.dp; import static org.floens.chan.utils.AndroidUtils.fixSnackbarText; -public class DrawerNavigationController extends NavigationController implements PinAdapter.Callback, View.OnClickListener { +public class DrawerController extends Controller implements PinAdapter.Callback, View.OnClickListener { private WatchManager watchManager; + protected FrameLayout container; protected DrawerLayout drawerLayout; protected LinearLayout drawer; protected RecyclerView recyclerView; protected LinearLayout settings; protected PinAdapter pinAdapter; - public DrawerNavigationController(Context context) { + private NavigationController childController; + + public DrawerController(Context context) { super(context); } @@ -77,8 +78,7 @@ public class DrawerNavigationController extends NavigationController implements EventBus.getDefault().register(this); view = inflateRes(R.layout.controller_navigation_drawer); - container = (ViewGroup) view.findViewById(R.id.container); - toolbar = (Toolbar) view.findViewById(R.id.toolbar); + container = (FrameLayout) view.findViewById(R.id.container); drawerLayout = (DrawerLayout) view.findViewById(R.id.drawer_layout); drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.LEFT); drawer = (LinearLayout) view.findViewById(R.id.drawer); @@ -89,8 +89,6 @@ public class DrawerNavigationController extends NavigationController implements theme().settingsDrawable.apply((ImageView) settings.findViewById(R.id.image)); ((TextView) settings.findViewById(R.id.text)).setTypeface(ROBOTO_MEDIUM); - toolbar.setBackgroundColor(ThemeHelper.getInstance().getTheme().primaryColor.color); - pinAdapter = new PinAdapter(this); recyclerView.setAdapter(pinAdapter); @@ -98,8 +96,6 @@ public class DrawerNavigationController extends NavigationController implements pinAdapter.onPinsChanged(watchManager.getPins()); - toolbar.setCallback(this); - updateBadge(); AndroidUtils.waitForMeasure(drawer, new AndroidUtils.OnMeasuredCallback() { @@ -114,9 +110,19 @@ public class DrawerNavigationController extends NavigationController implements public void onDestroy() { super.onDestroy(); + if (childController != null) { + childController.onDestroy(); + } + EventBus.getDefault().unregister(this); } + public void setChildController(NavigationController childController) { + childController.parentController = this; + ControllerLogic.transition(this.childController, childController, true, true, container); + this.childController = childController; + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -132,14 +138,11 @@ public class DrawerNavigationController extends NavigationController implements @Override public void onClick(View v) { if (v == settings) { - pushController(new MainSettingsController(context)); + openController(new MainSettingsController(context)); } } - @Override public void onMenuClicked() { - super.onMenuClicked(); - drawerLayout.openDrawer(drawer); } @@ -148,49 +151,31 @@ public class DrawerNavigationController extends NavigationController implements if (drawerLayout.isDrawerOpen(drawer)) { drawerLayout.closeDrawer(drawer); return true; + } else if (childController != null && childController.onBack()) { + return true; } else { return super.onBack(); } } - @Override - protected void controllerPushed(Controller controller) { - super.controllerPushed(controller); - setDrawerEnabled(controller.navigationItem.hasDrawer); - } - - @Override - protected void controllerPopped(Controller controller) { - super.controllerPopped(controller); - setDrawerEnabled(controller.navigationItem.hasDrawer); - } - - @Override - public void onControllerTransitionCompleted(ControllerTransition transition) { - super.onControllerTransitionCompleted(transition); - updateHighlighted(); - } - - public void updateHighlighted() { - pinAdapter.updateHighlighted(recyclerView); - } - @Override public void onPinClicked(Pin pin) { - Controller top = getTop(); - if (top instanceof DrawerCallback) { - ((DrawerCallback) top).onPinClicked(pin); - drawerLayout.closeDrawer(Gravity.LEFT); - pinAdapter.updateHighlighted(recyclerView); - } - } + drawerLayout.closeDrawer(Gravity.LEFT); - public boolean isHighlighted(Pin pin) { - Controller top = getTop(); - if (top instanceof DrawerCallback) { - return ((DrawerCallback) top).isPinCurrent(pin); + if (childController instanceof StyledToolbarNavigationController) { + if (childController.getTop() instanceof ThreadController) { + ((ThreadController) childController.getTop()).openPin(pin); + } + } else if (childController instanceof SplitNavigationController) { + SplitNavigationController splitNavigationController = (SplitNavigationController) childController; + if (splitNavigationController.leftController instanceof NavigationController) { + NavigationController navigationController = (NavigationController) splitNavigationController.leftController; + if (navigationController.getTop() instanceof ThreadController) { + ThreadController threadController = (ThreadController) navigationController.getTop(); + threadController.openPin(pin); + } + } } - return false; } @Override @@ -200,7 +185,7 @@ public class DrawerNavigationController extends NavigationController implements @Override public void onHeaderClicked(PinAdapter.HeaderHolder holder) { - pushController(new WatchSettingsController(context)); + openController(new WatchSettingsController(context)); } @Override @@ -251,12 +236,17 @@ public class DrawerNavigationController extends NavigationController implements @Override public void openBoardEditor() { - pushController(new BoardEditController(context)); + openController(new BoardEditController(context)); } @Override public void openHistory() { - pushController(new HistoryController(context)); + openController(new HistoryController(context)); + } + + public void setPinHighlighted(Pin pin) { + pinAdapter.setPinHighlighted(pin); + pinAdapter.updateHighlighted(recyclerView); } public void onEvent(WatchManager.PinAddedMessage message) { @@ -275,7 +265,7 @@ public class DrawerNavigationController extends NavigationController implements updateBadge(); } - private void setDrawerEnabled(boolean enabled) { + public void setDrawerEnabled(boolean enabled) { drawerLayout.setDrawerLockMode(enabled ? DrawerLayout.LOCK_MODE_UNLOCKED : DrawerLayout.LOCK_MODE_LOCKED_CLOSED, Gravity.LEFT); } @@ -292,7 +282,14 @@ public class DrawerNavigationController extends NavigationController implements } } - toolbar.getArrowMenuDrawable().setBadge(count, color); + if (childController instanceof StyledToolbarNavigationController) { + ((StyledToolbarNavigationController) childController).toolbar.getArrowMenuDrawable().setBadge(count, color); + } else if (childController instanceof SplitNavigationController) { + SplitNavigationController splitNavigationController = (SplitNavigationController) childController; + if (splitNavigationController.leftController instanceof StyledToolbarNavigationController) { + ((StyledToolbarNavigationController) splitNavigationController.leftController).toolbar.getArrowMenuDrawable().setBadge(count, color); + } + } } private boolean setDrawerWidth() { @@ -306,36 +303,8 @@ public class DrawerNavigationController extends NavigationController implements } } - @Override - public String getSearchHint() { - return context.getString(R.string.search_hint); - } - - @Override - public void onSearchVisibilityChanged(boolean visible) { - Controller top = getTop(); - if (top instanceof ToolbarSearchCallback) { - ((ToolbarSearchCallback) top).onSearchVisibilityChanged(visible); - } - } - - @Override - public void onSearchEntered(String entered) { - Controller top = getTop(); - if (top instanceof ToolbarSearchCallback) { - ((ToolbarSearchCallback) top).onSearchEntered(entered); - } - } - - public interface DrawerCallback { - void onPinClicked(Pin pin); - - boolean isPinCurrent(Pin pin); - } - - public interface ToolbarSearchCallback { - void onSearchVisibilityChanged(boolean visible); - - void onSearchEntered(String entered); + private void openController(Controller controller) { + childController.pushController(controller); + drawerLayout.closeDrawer(Gravity.LEFT); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java index acff3c22..bdc06369 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/FiltersController.java @@ -50,7 +50,7 @@ import static org.floens.chan.ui.theme.ThemeHelper.theme; import static org.floens.chan.utils.AndroidUtils.getAttrColor; import static org.floens.chan.utils.AndroidUtils.getString; -public class FiltersController extends Controller implements ToolbarMenuItem.ToolbarMenuItemCallback, DrawerNavigationController.ToolbarSearchCallback, View.OnClickListener { +public class FiltersController extends Controller implements ToolbarMenuItem.ToolbarMenuItemCallback, ToolbarNavigationController.ToolbarSearchCallback, View.OnClickListener { private static final int SEARCH_ID = 1; private static final int CLEAR_ID = 101; @@ -127,7 +127,7 @@ public class FiltersController extends Controller implements ToolbarMenuItem.Too @Override public void onMenuItemClicked(ToolbarMenuItem item) { if ((Integer) item.getId() == SEARCH_ID) { - navigationController.showSearch(); + ((ToolbarNavigationController) navigationController).showSearch(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/HistoryController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/HistoryController.java index 7c245f2c..0ca63be9 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/HistoryController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/HistoryController.java @@ -50,7 +50,7 @@ import java.util.Locale; import static org.floens.chan.ui.theme.ThemeHelper.theme; import static org.floens.chan.utils.AndroidUtils.dp; -public class HistoryController extends Controller implements CompoundButton.OnCheckedChangeListener, ToolbarMenuItem.ToolbarMenuItemCallback, DrawerNavigationController.ToolbarSearchCallback { +public class HistoryController extends Controller implements CompoundButton.OnCheckedChangeListener, ToolbarMenuItem.ToolbarMenuItemCallback, ToolbarNavigationController.ToolbarSearchCallback { private static final int SEARCH_ID = 1; private static final int CLEAR_ID = 101; @@ -94,7 +94,7 @@ public class HistoryController extends Controller implements CompoundButton.OnCh @Override public void onMenuItemClicked(ToolbarMenuItem item) { if ((Integer) item.getId() == SEARCH_ID) { - navigationController.showSearch(); + ((ToolbarNavigationController) navigationController).showSearch(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerNavigationController.java index d9008412..51491840 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerNavigationController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ImageViewerNavigationController.java @@ -18,17 +18,19 @@ package org.floens.chan.ui.controller; import android.content.Context; +import android.view.ViewGroup; import android.widget.FrameLayout; import org.floens.chan.R; import org.floens.chan.controller.NavigationController; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.PostImage; +import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.ui.toolbar.Toolbar; import java.util.List; -public class ImageViewerNavigationController extends NavigationController { +public class ImageViewerNavigationController extends ToolbarNavigationController { private ImageViewerController imageViewerController; public ImageViewerNavigationController(Context context) { @@ -40,9 +42,8 @@ public class ImageViewerNavigationController extends NavigationController { super.onCreate(); view = inflateRes(R.layout.controller_navigation_image_viewer); + container = (ViewGroup) view.findViewById(R.id.container); toolbar = (Toolbar) view.findViewById(R.id.toolbar); - container = (FrameLayout) view.findViewById(R.id.container); - toolbar.setCallback(this); imageViewerController = new ImageViewerController(context, toolbar); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java new file mode 100644 index 00000000..5f8fc7be --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/PopupController.java @@ -0,0 +1,79 @@ +/* + * 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 . + */ +package org.floens.chan.ui.controller; + +import android.content.Context; +import android.view.View; +import android.widget.FrameLayout; + +import org.floens.chan.R; +import org.floens.chan.controller.Controller; +import org.floens.chan.controller.ControllerLogic; +import org.floens.chan.controller.NavigationController; + +public class PopupController extends Controller implements View.OnClickListener { + private FrameLayout topView; + private FrameLayout container; + + private NavigationController childController; + + public PopupController(Context context) { + super(context); + } + + @Override + public void onCreate() { + super.onCreate(); + + view = inflateRes(R.layout.layout_controller_popup); + topView = (FrameLayout) view.findViewById(R.id.top_view); + topView.setOnClickListener(this); + container = (FrameLayout) view.findViewById(R.id.container); + } + + @Override + public void onDestroy() { + super.onDestroy(); + + if (childController != null) { + childController.onDestroy(); + } + } + + public void setChildController(NavigationController childController) { + childController.parentController = this; + ControllerLogic.transition(this.childController, childController, true, true, container); + this.childController = childController; + } + + @Override + public boolean onBack() { + return childController != null && childController.onBack(); + } + + @Override + public void onClick(View v) { + dismiss(); + } + + public void dismiss() { + if (presentingController instanceof SplitNavigationController) { + ((SplitNavigationController) presentingController).popAll(); + } + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java index c4c32eb7..cec13664 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/SplitNavigationController.java @@ -20,6 +20,7 @@ package org.floens.chan.ui.controller; import android.content.Context; import android.content.res.Configuration; import android.view.View; +import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; @@ -40,6 +41,10 @@ public class SplitNavigationController extends NavigationController implements A private FrameLayout leftControllerView; private FrameLayout rightControllerView; private View dividerView; + private ViewGroup emptyView; + + private PopupController popup; + private StyledToolbarNavigationController popupChild; public SplitNavigationController(Context context) { super(context); @@ -62,9 +67,27 @@ public class SplitNavigationController extends NavigationController implements A rightControllerView = new FrameLayout(context); wrap.addView(rightControllerView, new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1f)); + setRightController(null); + AndroidUtils.waitForMeasure(view, this); } + @Override + public void onDestroy() { + super.onDestroy(); + + if (leftController != null) { + leftController.onDestroy(); + } + if (rightController != null) { + rightController.onDestroy(); + } + } + + public void setEmptyView(ViewGroup emptyView) { + this.emptyView = emptyView; + } + public void setLeftController(Controller leftController) { leftController.navigationController = this; ControllerLogic.transition(this.leftController, leftController, true, true, leftControllerView); @@ -72,57 +95,67 @@ public class SplitNavigationController extends NavigationController implements A } public void setRightController(Controller rightController) { - rightController.navigationController = this; + if (rightController != null) { + rightController.navigationController = this; + } else { + rightControllerView.removeAllViews(); + } + ControllerLogic.transition(this.rightController, rightController, true, true, rightControllerView); this.rightController = rightController; - } - - @Override - public void transition(Controller from, Controller to, boolean pushing, ControllerTransition controllerTransition) { - if (this.controllerTransition != null) { - throw new IllegalArgumentException("Cannot transition while another transition is in progress."); - } - if (!pushing && controllerList.size() == 0) { - throw new IllegalArgumentException("Cannot pop with no controllers left"); + if (rightController == null) { + rightControllerView.addView(emptyView); } + } - if (controllerTransition != null) { - blockingInput = true; - this.controllerTransition = controllerTransition; - controllerTransition.setCallback(this); - ControllerLogic.startTransition(from, to, pushing, leftControllerView, controllerTransition); + @Override + public boolean pushController(Controller to, ControllerTransition controllerTransition) { + if (popup == null) { + popup = new PopupController(context); + presentController(popup); + popupChild = new StyledToolbarNavigationController(context); + popup.setChildController(popupChild); + popupChild.pushController(to, false); } else { - ControllerLogic.transition(from, to, pushing, leftControllerView); - if (!pushing) { - controllerList.remove(from); - } + popupChild.pushController(to, controllerTransition); } - if (to != null) { - toolbar.setNavigationItem(controllerTransition != null, false, to.navigationItem); - - updateToolbarCollapse(to, controllerTransition != null); + return true; + } - if (pushing) { - controllerPushed(to); + @Override + public boolean popController(ControllerTransition controllerTransition) { + if (popup != null) { + if (popupChild.getControllerList().size() == 1) { + presentedController.stopPresenting(); + popup = null; + popupChild = null; } else { - controllerPopped(to); + popupChild.popController(controllerTransition); } + return true; + } else { + return false; + } + } + + public void popAll() { + if (popup != null) { + presentedController.stopPresenting(); + popup = null; + popupChild = null; } } @Override public boolean onBack() { - if (!super.onBack()) { - if (rightController != null && rightController.onBack()) { - return true; - } - if (leftController != null && leftController.onBack()) { - return true; - } + if (leftController != null && leftController.onBack()) { + return true; + } else if (rightController != null && rightController.onBack()) { + return true; } - return false; + return super.onBack(); } @Override diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java new file mode 100644 index 00000000..68453d91 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/StyledToolbarNavigationController.java @@ -0,0 +1,100 @@ +/* + * 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 . + */ +package org.floens.chan.ui.controller; + +import android.content.Context; +import android.view.ViewGroup; + +import org.floens.chan.R; +import org.floens.chan.controller.Controller; +import org.floens.chan.controller.ControllerTransition; +import org.floens.chan.ui.theme.ThemeHelper; +import org.floens.chan.ui.toolbar.Toolbar; + +public class StyledToolbarNavigationController extends ToolbarNavigationController { + public StyledToolbarNavigationController(Context context) { + super(context); + } + + @Override + public void onCreate() { + super.onCreate(); + + view = inflateRes(R.layout.controller_navigation_toolbar); + container = (ViewGroup) view.findViewById(R.id.container); + toolbar = (Toolbar) view.findViewById(R.id.toolbar); + toolbar.setBackgroundColor(ThemeHelper.getInstance().getTheme().primaryColor.color); + toolbar.setCallback(this); + } + + @Override + public void transition(Controller from, Controller to, boolean pushing, ControllerTransition controllerTransition) { + super.transition(from, to, pushing, controllerTransition); + + if (to != null) { + DrawerController drawerController = getDrawerController(); + if (drawerController != null) { + drawerController.setDrawerEnabled(to.navigationItem.hasDrawer); + } + } + } + + @Override + public boolean onBack() { + if (super.onBack()) { + return true; + } else if (parentController instanceof PopupController && controllerList.size() == 1) { + ((PopupController) parentController).dismiss(); + return true; + } else if (navigationController instanceof SplitNavigationController && controllerList.size() == 1) { + SplitNavigationController splitNavigationController = (SplitNavigationController) navigationController; + if (splitNavigationController.rightController == this) { + splitNavigationController.setRightController(null); + return true; + } else { + return false; + } + } else { + return false; + } + } + + @Override + public void onMenuOrBackClicked(boolean isArrow) { + if (isArrow) { + onBack(); + } else { + DrawerController drawerController = getDrawerController(); + if (drawerController != null) { + drawerController.onMenuClicked(); + } + } + } + + private DrawerController getDrawerController() { + if (parentController instanceof DrawerController) { + return (DrawerController) parentController; + } else if (navigationController instanceof SplitNavigationController) { + SplitNavigationController splitNavigationController = (SplitNavigationController) navigationController; + if (splitNavigationController.parentController instanceof DrawerController) { + return (DrawerController) splitNavigationController.parentController; + } + } + return null; + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java index 4ef0261f..b9e4a0e5 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThreadController.java @@ -30,6 +30,7 @@ import org.floens.chan.R; import org.floens.chan.chan.ChanUrls; import org.floens.chan.controller.Controller; import org.floens.chan.core.model.Loadable; +import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.PostImage; import org.floens.chan.ui.helper.RefreshUIMessage; import org.floens.chan.ui.layout.ThreadLayout; @@ -42,8 +43,9 @@ import java.util.List; import de.greenrobot.event.EventBus; import static org.floens.chan.utils.AndroidUtils.dp; +import static org.floens.chan.utils.AndroidUtils.isTablet; -public abstract class ThreadController extends Controller implements ThreadLayout.ThreadLayoutCallback, ImageViewerController.PreviewCallback, DrawerNavigationController.DrawerCallback, SwipeRefreshLayout.OnRefreshListener, DrawerNavigationController.ToolbarSearchCallback, NfcAdapter.CreateNdefMessageCallback { +public abstract class ThreadController extends Controller implements ThreadLayout.ThreadLayoutCallback, ImageViewerController.PreviewCallback, SwipeRefreshLayout.OnRefreshListener, ToolbarNavigationController.ToolbarSearchCallback, NfcAdapter.CreateNdefMessageCallback { private static final String TAG = "ThreadController"; protected ThreadLayout threadLayout; @@ -59,7 +61,7 @@ public abstract class ThreadController extends Controller implements ThreadLayou EventBus.getDefault().register(this); - navigationItem.collapseToolbar = true; + navigationItem.collapseToolbar = !isTablet(context); threadLayout = (ThreadLayout) LayoutInflater.from(context).inflate(R.layout.layout_thread, null); threadLayout.setCallback(this); @@ -73,8 +75,12 @@ public abstract class ThreadController extends Controller implements ThreadLayou swipeRefreshLayout.addView(threadLayout); swipeRefreshLayout.setOnRefreshListener(this); - int toolbarHeight = navigationController.getToolbar() == null ? 0 : navigationController.getToolbar().getToolbarHeight(); - swipeRefreshLayout.setProgressViewOffset(false, toolbarHeight - dp(40), toolbarHeight + dp(64 - 40)); + ToolbarNavigationController toolbarNavigationController = (ToolbarNavigationController) navigationController; + + if (collapseToolbar()) { + int toolbarHeight = getToolbar().getToolbarHeight(); + swipeRefreshLayout.setProgressViewOffset(false, toolbarHeight - dp(40), toolbarHeight + dp(64 - 40)); + } view = swipeRefreshLayout; } @@ -88,6 +94,8 @@ public abstract class ThreadController extends Controller implements ThreadLayou EventBus.getDefault().unregister(this); } + public abstract void openPin(Pin pin); + /* * Used to save instance state */ @@ -186,7 +194,12 @@ public abstract class ThreadController extends Controller implements ThreadLayou @Override public Toolbar getToolbar() { - return navigationController.getToolbar(); + return ((ToolbarNavigationController) navigationController).getToolbar(); + } + + @Override + public boolean collapseToolbar() { + return navigationItem.collapseToolbar; } @Override diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java new file mode 100644 index 00000000..7035ad2f --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ToolbarNavigationController.java @@ -0,0 +1,103 @@ +/* + * 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 . + */ +package org.floens.chan.ui.controller; + +import android.content.Context; +import android.widget.FrameLayout; + +import org.floens.chan.R; +import org.floens.chan.controller.Controller; +import org.floens.chan.controller.ControllerTransition; +import org.floens.chan.controller.NavigationController; +import org.floens.chan.ui.toolbar.Toolbar; + +public abstract class ToolbarNavigationController extends NavigationController implements Toolbar.ToolbarCallback { + protected Toolbar toolbar; + + public ToolbarNavigationController(Context context) { + super(context); + } + + public Toolbar getToolbar() { + return toolbar; + } + + public void showSearch() { + toolbar.openSearch(); + } + + @Override + public void transition(Controller from, Controller to, boolean pushing, ControllerTransition controllerTransition) { + super.transition(from, to, pushing, controllerTransition); + + if (to != null) { + toolbar.setNavigationItem(controllerTransition != null, pushing, to.navigationItem); + updateToolbarCollapse(to, controllerTransition != null); + } + } + + @Override + public void onMenuOrBackClicked(boolean isArrow) { + } + + @Override + public boolean onBack() { + return toolbar.closeSearch() || super.onBack(); + } + + @Override + public String getSearchHint() { + return context.getString(R.string.search_hint); + } + + @Override + public void onSearchVisibilityChanged(boolean visible) { + Controller top = getTop(); + if (top instanceof ToolbarSearchCallback) { + ((ToolbarSearchCallback) top).onSearchVisibilityChanged(visible); + } + } + + @Override + public void onSearchEntered(String entered) { + Controller top = getTop(); + if (top instanceof ToolbarSearchCallback) { + ((ToolbarSearchCallback) top).onSearchEntered(entered); + } + } + + protected void updateToolbarCollapse(Controller controller, boolean animate) { + if (!controller.navigationItem.collapseToolbar) { + FrameLayout.LayoutParams toViewParams = (FrameLayout.LayoutParams) controller.view.getLayoutParams(); + toViewParams.topMargin = toolbar.getToolbarHeight(); + controller.view.setLayoutParams(toViewParams); + } + + toolbar.processScrollCollapse(Toolbar.TOOLBAR_COLLAPSE_SHOW, animate); + } + + public interface ToolbarSearchCallback { + void onSearchVisibilityChanged(boolean visible); + + void onSearchEntered(String entered); + } + + public interface ToolbarMenuCallback { + void onMenuOrBackClicked(boolean isArrow); + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java index 585b9bc5..e65cf404 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ViewThreadController.java @@ -79,20 +79,18 @@ public class ViewThreadController extends ThreadController implements ThreadLayo new FloatingMenuItem(DOWN_ID, context.getString(R.string.action_down)) )); - loadLoadable(loadable); + loadThread(loadable); } @Override - public void onShow() { - super.onShow(); - if (navigationController instanceof DrawerNavigationController) { - ((DrawerNavigationController) navigationController).updateHighlighted(); - } + public void onDestroy() { + super.onDestroy(); + updateDrawerHighlighting(null); } @Override - public void onDestroy() { - super.onDestroy(); + public void openPin(Pin pin) { + loadThread(pin.loadable); } public void onEvent(WatchManager.PinAddedMessage message) { @@ -114,10 +112,7 @@ public class ViewThreadController extends ThreadController implements ThreadLayo .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(final DialogInterface dialog, final int which) { - loadLoadable(threadLoadable); - if (navigationController instanceof DrawerNavigationController) { - ((DrawerNavigationController) navigationController).updateHighlighted(); - } + loadThread(threadLoadable); } }) .setTitle(R.string.open_thread_confirmation) @@ -125,17 +120,7 @@ public class ViewThreadController extends ThreadController implements ThreadLayo .show(); } - @Override - public void onPinClicked(Pin pin) { - loadLoadable(pin.loadable); - } - - @Override - public boolean isPinCurrent(Pin pin) { - return pin.loadable.equals(threadLayout.getPresenter().getLoadable()); - } - - public void loadLoadable(Loadable loadable) { + public void loadThread(Loadable loadable) { if (!loadable.equals(threadLayout.getPresenter().getLoadable())) { threadLayout.getPresenter().bindLoadable(loadable); this.loadable = threadLayout.getPresenter().getLoadable(); @@ -143,6 +128,8 @@ public class ViewThreadController extends ThreadController implements ThreadLayo navigationItem.title = loadable.title; navigationItem.updateTitle(); setPinIconState(threadLayout.getPresenter().isPinned()); + + updateDrawerHighlighting(loadable); } } @@ -172,7 +159,7 @@ public class ViewThreadController extends ThreadController implements ThreadLayo threadLayout.getPresenter().requestData(); break; case SEARCH_ID: - navigationController.showSearch(); + ((ToolbarNavigationController) navigationController).showSearch(); break; case SHARE_ID: case OPEN_BROWSER_ID: @@ -194,6 +181,19 @@ public class ViewThreadController extends ThreadController implements ThreadLayo } } + private void updateDrawerHighlighting(Loadable loadable) { + WatchManager wm = Chan.getWatchManager(); + Pin pin = loadable == null ? null : wm.findPinByLoadable(loadable); + + if (navigationController.parentController instanceof DrawerController) { + ((DrawerController) navigationController.parentController).setPinHighlighted(pin); + } else if (navigationController.navigationController instanceof SplitNavigationController) { + if (((SplitNavigationController) navigationController.navigationController).parentController instanceof DrawerController) { + ((DrawerController) ((SplitNavigationController) navigationController.navigationController).parentController).setPinHighlighted(pin); + } + } + } + private void setPinIconState() { WatchManager wm = Chan.getWatchManager(); setPinIconState(wm.findPinByLoadable(loadable) != null); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/PostRepliesContainer.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/PostRepliesContainer.java new file mode 100644 index 00000000..72354651 --- /dev/null +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/PostRepliesContainer.java @@ -0,0 +1,49 @@ +/* + * 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 . + */ +package org.floens.chan.ui.layout; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import static org.floens.chan.utils.AndroidUtils.dp; + +public class PostRepliesContainer extends LinearLayout { + public PostRepliesContainer(Context context) { + super(context); + } + + public PostRepliesContainer(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public PostRepliesContainer(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int maxWidth = dp(600); + + if (MeasureSpec.getSize(widthMeasureSpec) > maxWidth) { + widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.getMode(widthMeasureSpec)); + } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } +} diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java index 9e28c41c..5dc3497f 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadLayout.java @@ -183,6 +183,11 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T return callback.getToolbar(); } + @Override + public boolean collapseToolbar() { + return callback.collapseToolbar(); + } + @Override public void showPosts(ChanThread thread, PostsFilter filter) { threadListLayout.showPosts(thread, filter, visible != Visible.THREAD); @@ -496,5 +501,7 @@ public class ThreadLayout extends CoordinatorLayout implements ThreadPresenter.T void hideSwipeRefreshLayout(); Toolbar getToolbar(); + + boolean collapseToolbar(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java index 257eea54..bdf6f77a 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ThreadListLayout.java @@ -66,7 +66,6 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL private PostCellInterface.PostViewMode postViewMode; private int spanCount = 2; private int background; - private Toolbar toolbar; private boolean searchOpen; public ThreadListLayout(Context context, AttributeSet attrs) { @@ -100,19 +99,17 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL // onScrolled can be called after cleanup() if (showingThread != null) { int index = Math.max(0, getTopAdapterPosition()); - int top = recyclerView.getLayoutManager().getChildAt(0).getTop(); +// int top = recyclerView.getLayoutManager().getChildAt(0).getTop(); showingThread.loadable.listViewIndex = index; // showingThread.loadable.listViewTop = top; } } }); - toolbar = threadListLayoutCallback.getToolbar(); attachToolbarScroll(true); - int toolbarHeight = toolbar == null ? 0 : toolbar.getToolbarHeight(); - reply.setPadding(0, toolbarHeight, 0, 0); - searchStatus.setPadding(searchStatus.getPaddingLeft(), searchStatus.getPaddingTop() + toolbarHeight, + reply.setPadding(0, topSpacing(), 0, 0); + searchStatus.setPadding(searchStatus.getPaddingLeft(), searchStatus.getPaddingTop() + topSpacing(), searchStatus.getPaddingRight(), searchStatus.getPaddingBottom()); } @@ -139,11 +136,10 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL layoutManager = null; - int toolbarHeight = toolbar == null ? 0 : toolbar.getToolbarHeight(); switch (postViewMode) { case LIST: LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext()); - recyclerView.setPadding(0, toolbarHeight, 0, 0); + recyclerView.setPadding(0, topSpacing(), 0, 0); recyclerView.setLayoutManager(linearLayoutManager); layoutManager = linearLayoutManager; @@ -156,7 +152,7 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL case CARD: GridLayoutManager gridLayoutManager = new GridLayoutManager(null, spanCount, GridLayoutManager.VERTICAL, false); // The cards have a 4dp padding, this way there is always 8dp between the edges - recyclerView.setPadding(dp(4), dp(4) + toolbarHeight, dp(4), dp(4)); + recyclerView.setPadding(dp(4), dp(4) + topSpacing(), dp(4), dp(4)); recyclerView.setLayoutManager(gridLayoutManager); layoutManager = gridLayoutManager; @@ -276,18 +272,17 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL return true; } - int toolbarHeight = toolbar == null ? 0 : toolbar.getToolbarHeight(); switch (postViewMode) { case LIST: if (getTopAdapterPosition() == 0) { View top = layoutManager.findViewByPosition(0); - return top.getTop() != toolbarHeight; + return top.getTop() != topSpacing(); } break; case CARD: if (getTopAdapterPosition() == 0) { View top = layoutManager.findViewByPosition(0); - return top.getTop() != dp(8) + toolbarHeight; // 4dp for the cards, 4dp for this layout + return top.getTop() != dp(8) + topSpacing(); // 4dp for the cards, 4dp for this layout } break; } @@ -400,7 +395,8 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } private void attachToolbarScroll(boolean attach) { - if (toolbar != null) { + Toolbar toolbar = threadListLayoutCallback.getToolbar(); + if (toolbar != null && threadListLayoutCallback.collapseToolbar()) { if (attach) { toolbar.attachRecyclerViewScrollStateListener(recyclerView); } else { @@ -410,6 +406,15 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL } } + private int topSpacing() { + Toolbar toolbar = threadListLayoutCallback.getToolbar(); + if (toolbar != null && threadListLayoutCallback.collapseToolbar()) { + return toolbar.getToolbarHeight(); + } else { + return 0; + } + } + private int getTopAdapterPosition() { switch (postViewMode) { case LIST: @@ -440,5 +445,7 @@ public class ThreadListLayout extends LinearLayout implements ReplyLayout.ReplyL void replyLayoutOpen(boolean open); Toolbar getToolbar(); + + boolean collapseToolbar(); } } diff --git a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java index 24676df7..605c1d0d 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/toolbar/Toolbar.java @@ -141,6 +141,10 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV setNavigationItem(false, false, navigationItem); } + public NavigationItem getNavigationItem() { + return navigationItem; + } + public boolean openSearch() { return openSearchInternal(); } @@ -223,7 +227,7 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV } private boolean openSearchInternal() { - if (!navigationItem.search) { + if (navigationItem != null && !navigationItem.search) { navigationItem.search = true; openKeyboardAfterSearchViewCreated = true; setNavigationItem(true, true, navigationItem); @@ -236,7 +240,7 @@ public class Toolbar extends LinearLayout implements View.OnClickListener, LoadV } private boolean closeSearchInternal() { - if (navigationItem.search) { + if (navigationItem != null && navigationItem.search) { navigationItem.search = false; navigationItem.searchText = null; setNavigationItemInternal(true, false, navigationItem); diff --git a/Clover/app/src/main/res/layout/controller_navigation_drawer.xml b/Clover/app/src/main/res/layout/controller_navigation_drawer.xml index a7acf10e..77db5b6d 100644 --- a/Clover/app/src/main/res/layout/controller_navigation_drawer.xml +++ b/Clover/app/src/main/res/layout/controller_navigation_drawer.xml @@ -22,23 +22,9 @@ along with this program. If not, see . android:layout_height="match_parent"> - - - - - - + android:layout_height="match_parent" /> + + + + + + + diff --git a/Clover/app/src/main/res/layout/layout_controller_popup.xml b/Clover/app/src/main/res/layout/layout_controller_popup.xml new file mode 100644 index 00000000..21cc6d66 --- /dev/null +++ b/Clover/app/src/main/res/layout/layout_controller_popup.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/Clover/app/src/main/res/layout/layout_post_replies.xml b/Clover/app/src/main/res/layout/layout_post_replies.xml index fd50a5f0..c68cde92 100644 --- a/Clover/app/src/main/res/layout/layout_post_replies.xml +++ b/Clover/app/src/main/res/layout/layout_post_replies.xml @@ -21,7 +21,7 @@ along with this program. If not, see . android:layout_width="match_parent" android:layout_height="match_parent"> - . android:layout_width="match_parent" android:layout_height="match_parent" /> - + diff --git a/Clover/app/src/main/res/layout/layout_post_replies_bottombuttons.xml b/Clover/app/src/main/res/layout/layout_post_replies_bottombuttons.xml index bc6be829..b8c8b2c4 100644 --- a/Clover/app/src/main/res/layout/layout_post_replies_bottombuttons.xml +++ b/Clover/app/src/main/res/layout/layout_post_replies_bottombuttons.xml @@ -21,7 +21,7 @@ along with this program. If not, see . android:layout_width="match_parent" android:layout_height="match_parent"> - . - + diff --git a/Clover/app/src/main/res/layout/layout_split_empty.xml b/Clover/app/src/main/res/layout/layout_split_empty.xml new file mode 100644 index 00000000..0c8f27ca --- /dev/null +++ b/Clover/app/src/main/res/layout/layout_split_empty.xml @@ -0,0 +1,32 @@ + + + + + + diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml index 1e882ed0..21037440 100644 --- a/Clover/app/src/main/res/values/strings.xml +++ b/Clover/app/src/main/res/values/strings.xml @@ -113,6 +113,7 @@ along with this program. If not, see . Closed %1$d new %2$s View + Please select a thread Board editor Add, remove and reorder your boards here.\nThe topmost board will be loaded automatically. diff --git a/Clover/app/src/main/res/values/styles.xml b/Clover/app/src/main/res/values/styles.xml index 9b12d9c2..8a628096 100644 --- a/Clover/app/src/main/res/values/styles.xml +++ b/Clover/app/src/main/res/values/styles.xml @@ -81,6 +81,7 @@ along with this program. If not, see . #4cffffff #1effffff + #ff3d3d3d #ff5C5C5C #ff444444