add hint to add site, rework intro flow.

multisite
Floens 8 years ago
parent a15e70630e
commit 9b38f11efe
  1. 23
      Clover/app/src/main/java/org/floens/chan/core/presenter/SitesSetupPresenter.java
  2. 4
      Clover/app/src/main/java/org/floens/chan/core/site/SiteManager.java
  3. 21
      Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java
  4. 5
      Clover/app/src/main/java/org/floens/chan/ui/controller/IntroController.java
  5. 2
      Clover/app/src/main/java/org/floens/chan/ui/controller/MainSettingsController.java
  6. 28
      Clover/app/src/main/java/org/floens/chan/ui/controller/SitesSetupController.java
  7. 73
      Clover/app/src/main/java/org/floens/chan/ui/helper/HintPopup.java
  8. 16
      Clover/app/src/main/java/org/floens/chan/ui/helper/VersionHandler.java
  9. 12
      Clover/app/src/main/java/org/floens/chan/ui/layout/SiteAddLayout.java
  10. 1
      Clover/app/src/main/res/layout/controller_intro.xml
  11. 48
      Clover/app/src/main/res/layout/popup_hint_top.xml
  12. 1
      Clover/app/src/main/res/values/strings.xml

@ -50,7 +50,17 @@ public class SitesSetupPresenter {
this.callback.setAddedSites(sites);
this.callback.setNextAllowed(!sites.isEmpty(), false);
this.callback.setNextAllowed(!sites.isEmpty());
if (sites.isEmpty()) {
callback.presentIntro();
}
}
public void onIntroDismissed() {
if (sites.isEmpty()) {
callback.showHint();
}
}
public void bindAddDialog(AddCallback addCallback) {
@ -74,6 +84,7 @@ public class SitesSetupPresenter {
@Override
public void onSiteAdded(Site site) {
siteAdded(site);
addCallback.dismissDialog();
}
@Override
@ -96,7 +107,7 @@ public class SitesSetupPresenter {
callback.setAddedSites(sites);
callback.setNextAllowed(!sites.isEmpty(), true);
callback.setNextAllowed(!sites.isEmpty());
}
public void onSiteCellSettingsClicked(Site site) {
@ -104,16 +115,22 @@ public class SitesSetupPresenter {
}
public interface Callback {
void presentIntro();
void showHint();
void showAddDialog();
void setAddedSites(List<Site> sites);
void setNextAllowed(boolean nextAllowed, boolean animate);
void setNextAllowed(boolean nextAllowed);
void openSiteConfiguration(Site site);
}
public interface AddCallback {
void showAddError(String error);
void dismissDialog();
}
}

@ -46,6 +46,10 @@ public class SiteManager {
this.resolver = resolver;
}
public boolean areSitesSetup() {
return !Sites.allSites().isEmpty();
}
public void addSite(String url, SiteAddCallback callback) {
Site existing = resolver.findSiteForUrl(url);
if (existing != null) {

@ -45,12 +45,13 @@ import org.floens.chan.core.model.orm.Loadable;
import org.floens.chan.core.model.orm.Pin;
import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.core.site.Site;
import org.floens.chan.core.site.SiteManager;
import org.floens.chan.core.site.SiteResolver;
import org.floens.chan.core.site.Sites;
import org.floens.chan.ui.controller.BrowseController;
import org.floens.chan.ui.controller.DoubleNavigationController;
import org.floens.chan.ui.controller.DrawerController;
import org.floens.chan.ui.controller.SetupController;
import org.floens.chan.ui.controller.SitesSetupController;
import org.floens.chan.ui.controller.SplitNavigationController;
import org.floens.chan.ui.controller.StyledToolbarNavigationController;
import org.floens.chan.ui.controller.ThreadSlideController;
@ -98,6 +99,9 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
@Inject
SiteResolver siteResolver;
@Inject
SiteManager siteManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -146,12 +150,15 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
// Not from a state or from an url, launch the setup controller if no boards are setup up yet,
// otherwise load the default saved board.
if (!handled) {
/*if (boardManager.getSavedBoards().isEmpty()) {
setupWithNoBoards();
restoreFresh();
}
}
private void restoreFresh() {
if (!siteManager.areSitesSetup()) {
mainNavigationController.pushController(new SitesSetupController(this), false);
} else {
browseController.loadWithDefaultBoard();
}*/
browseController.loadWithDefaultBoard();
}
}
@ -209,10 +216,6 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
return handled;
}
private void setupWithNoBoards() {
mainNavigationController.presentController(new SetupController(this), false);
}
private Pair<Loadable, Loadable> resolveChanState(ChanState state) {
DatabaseLoadableManager loadableManager = databaseManager.getDatabaseLoadableManager();

@ -23,7 +23,6 @@ import android.widget.Button;
import org.floens.chan.R;
import org.floens.chan.controller.Controller;
import org.floens.chan.core.presenter.SetupPresenter;
public class IntroController extends Controller implements View.OnClickListener {
private Button start;
@ -45,8 +44,8 @@ public class IntroController extends Controller implements View.OnClickListener
@Override
public void onClick(View v) {
if (v == start) {
SetupPresenter presenter = ((SetupController) navigationController).getPresenter();
presenter.startClicked();
((SitesSetupController) presentedByController).onIntroDismissed();
stopPresenting();
}
}
}

@ -77,7 +77,7 @@ public class MainSettingsController extends SettingsController implements Toolba
private ChanSettings.LayoutMode previousLayoutMode;
private PopupWindow advancedSettingsHint;
private HintPopup advancedSettingsHint;
@Inject
DatabaseManager databaseManager;

@ -36,6 +36,7 @@ import org.floens.chan.R;
import org.floens.chan.core.presenter.SitesSetupPresenter;
import org.floens.chan.core.site.Site;
import org.floens.chan.core.site.SiteIcon;
import org.floens.chan.ui.helper.HintPopup;
import org.floens.chan.ui.layout.SiteAddLayout;
import org.floens.chan.ui.toolbar.ToolbarMenu;
import org.floens.chan.ui.toolbar.ToolbarMenuItem;
@ -132,6 +133,22 @@ public class SitesSetupController extends StyledToolbarNavigationController impl
}
}
@Override
public void presentIntro() {
presentController(new IntroController(context), false);
}
public void onIntroDismissed() {
presenter.onIntroDismissed();
}
@Override
public void showHint() {
String s = context.getString(R.string.setup_sites_add_hint);
HintPopup popup = new HintPopup(context, addButton, s, 0, 0, true);
popup.show();
}
@Override
public void showAddDialog() {
@SuppressLint("InflateParams") final SiteAddLayout dialogView =
@ -145,7 +162,11 @@ public class SitesSetupController extends StyledToolbarNavigationController impl
.setTitle(R.string.setup_sites_add_title)
.setPositiveButton(R.string.add, null)
.setNegativeButton(R.string.cancel, null)
.show();
.create();
dialogView.setDialog(dialog);
dialog.show();
Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
positiveButton.setOnClickListener((v) -> {
@ -168,10 +189,13 @@ public class SitesSetupController extends StyledToolbarNavigationController impl
}
@Override
public void setNextAllowed(boolean nextAllowed, boolean animate) {
public void setNextAllowed(boolean nextAllowed) {
if (doneMenuItem != null) {
doneMenuItem.getView().animate().alpha(nextAllowed ? 1f : 0f).start();
}
if (!nextAllowed) {
navigationItem.swipeable = false;
}
}
private void onSiteCellSettingsClicked(Site site) {

@ -17,6 +17,7 @@
*/
package org.floens.chan.ui.helper;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
@ -28,51 +29,79 @@ import android.widget.PopupWindow;
import android.widget.TextView;
import org.floens.chan.R;
import org.floens.chan.utils.AndroidUtils;
import static org.floens.chan.utils.AndroidUtils.dp;
import static org.floens.chan.utils.AndroidUtils.getString;
public class HintPopup {
public static PopupWindow show(Context context, View anchor, int text) {
public static HintPopup show(Context context, View anchor, int text) {
return show(context, anchor, getString(text));
}
public static PopupWindow show(final Context context, final View anchor, final String text) {
public static HintPopup show(final Context context, final View anchor, final String text) {
return show(context, anchor, text, 0, 0);
}
public static PopupWindow show(final Context context, final View anchor, final String text, final int offsetX, final int offsetY) {
final LinearLayout popupView = (LinearLayout) LayoutInflater.from(context).inflate(R.layout.popup_hint, null);
public static HintPopup show(final Context context, final View anchor, final String text, final int offsetX, final int offsetY) {
HintPopup hintPopup = new HintPopup(context, anchor, text, offsetX, offsetY, false);
hintPopup.show();
return hintPopup;
}
private TextView textView;
private PopupWindow popupWindow;
private LinearLayout popupView;
private final View anchor;
private String text;
private final int offsetX;
private final int offsetY;
private final boolean top;
private boolean dismissed;
public HintPopup(Context context, final View anchor, final String text, final int offsetX, final int offsetY, final boolean top) {
this.anchor = anchor;
this.text = text;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.top = top;
createView(context);
}
@SuppressLint("InflateParams")
private void createView(Context context) {
popupView = (LinearLayout) LayoutInflater.from(context)
.inflate(top ? R.layout.popup_hint_top : R.layout.popup_hint, null);
TextView textView = (TextView) popupView.findViewById(R.id.text);
textView = popupView.findViewById(R.id.text);
textView.setText(text);
final PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
popupWindow.setOutsideTouchable(true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
popupView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
popupWindow.dismiss();
}
popupView.setOnClickListener(v -> {
// popupWindow.dismiss();
});
}
popupView.postDelayed(new Runnable() {
@Override
public void run() {
public void show() {
AndroidUtils.runOnUiThread(() -> {
if (!dismissed) {
popupView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
popupWindow.showAsDropDown(anchor, -popupView.getMeasuredWidth() + anchor.getWidth() + offsetX, -dp(25) + offsetY);
// TODO: cleanup
int xoff = -popupView.getMeasuredWidth() + anchor.getWidth() + offsetX - dp(2);
int yoff = -dp(25) + offsetY + (top ? -anchor.getHeight() - dp(30) : 0);
popupWindow.showAsDropDown(anchor, xoff, yoff);
}
}, 100);
}, 400);
popupView.postDelayed(new Runnable() {
@Override
public void run() {
popupWindow.dismiss();
// popupView.postDelayed(popupWindow::dismiss, 5000);
}
}, 5000);
return popupWindow;
public void dismiss() {
popupWindow.dismiss();
dismissed = true;
}
}

@ -92,13 +92,11 @@ public class VersionHandler implements UpdateManager.UpdateCallback {
public void run() {
int previous = ChanSettings.previousVersion.get();
if (previous < CURRENT_VERSION) {
if (previous < 1) {
cleanupOutdatedIonFolder(context);
}
// Add more previous version checks here
handleUpdate(previous);
if (previous != 0) {
showMessage(CURRENT_VERSION);
}
ChanSettings.previousVersion.set(CURRENT_VERSION);
@ -111,6 +109,14 @@ public class VersionHandler implements UpdateManager.UpdateCallback {
}
}
private void handleUpdate(int previous) {
if (previous < 1) {
cleanupOutdatedIonFolder(context);
}
// Add more previous version checks here
}
public boolean isUpdatingAvailable() {
return updateManager.isUpdatingAvailable();
}

@ -1,5 +1,6 @@
package org.floens.chan.ui.layout;
import android.app.Dialog;
import android.content.Context;
import android.support.constraint.ConstraintLayout;
import android.support.design.widget.TextInputLayout;
@ -12,6 +13,8 @@ import org.floens.chan.core.presenter.SitesSetupPresenter;
public class SiteAddLayout extends ConstraintLayout implements SitesSetupPresenter.AddCallback {
private EditText url;
private TextInputLayout urlContainer;
private Dialog dialog;
private SitesSetupPresenter presenter;
public SiteAddLayout(Context context) {
@ -34,6 +37,10 @@ public class SiteAddLayout extends ConstraintLayout implements SitesSetupPresent
url = findViewById(R.id.url);
}
public void setDialog(Dialog dialog) {
this.dialog = dialog;
}
public void setPresenter(SitesSetupPresenter presenter) {
this.presenter = presenter;
}
@ -58,4 +65,9 @@ public class SiteAddLayout extends ConstraintLayout implements SitesSetupPresent
public void showAddError(String error) {
urlContainer.setError(error);
}
@Override
public void dismissDialog() {
dialog.dismiss();
}
}

@ -19,6 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?backcolor"
android:orientation="vertical">
<ImageView

@ -0,0 +1,48 @@
<?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="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="5dp">
<FrameLayout
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/background_accent_rounded">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:textColor="#ffffff" />
</FrameLayout>
<FrameLayout
android:id="@+id/arrow"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_gravity="right"
android:layout_marginRight="14dp"
android:background="@drawable/background_hint_arrow"
android:rotation="180" />
</LinearLayout>

@ -169,6 +169,7 @@ Re-enable this permission in the app settings if you permanently disabled it."</
<string name="intro_start">Get started</string>
<string name="setup_sites_title">Your sites</string>
<string name="setup_sites_add_hint">Add sites</string>
<string name="setup_sites_add_title">Add site</string>
<string name="setup_sites_url">Site url</string>
<string name="setup_sites_url_hint">http://</string>

Loading…
Cancel
Save