diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index fd302031..f893c565 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -133,6 +133,9 @@ + + + + + + + + + + tmpArrayList = new ArrayList<>(); + tmpArrayList.add(bookmark); + SharedPreferences.Editor widgetSharedPrefsEditor = widgetSharedPrefs.edit(); + + if (type == BookmarksFragment.Type.TOPIC) { + widgetSharedPrefsEditor.putString(BOOKMARK_WIDGETS_KEY + "_t_" + mAppWidgetId, Bookmark.arrayListToString(tmpArrayList)); + } else if (type == BookmarksFragment.Type.BOARD) { + widgetSharedPrefsEditor.putString(BOOKMARK_WIDGETS_KEY + "_b_" + mAppWidgetId, Bookmark.arrayListToString(tmpArrayList)); + } else { + finish(); + } + widgetSharedPrefsEditor.apply(); + + // Push widget update to surface + AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this); + WidgetProvider.updateAppWidget(this, appWidgetManager, mAppWidgetId, 0); // Todo: check if there are already notifications available + + // Make sure we pass back the original appWidgetId + Intent resultValue = new Intent(); + resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); + setResult(RESULT_OK, resultValue); + finish(); + } + /** * A {@link FragmentPagerAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. If it becomes too memory intensive, @@ -143,6 +221,7 @@ public class BookmarksActivity extends BaseActivity { notifyDataSetChanged(); } + @NonNull @Override public Fragment getItem(int position) { return fragmentList.get(position); @@ -159,7 +238,7 @@ public class BookmarksActivity extends BaseActivity { } @Override - public int getItemPosition(Object object) { + public int getItemPosition(@NonNull Object object) { @SuppressWarnings("RedundantCast") int position = fragmentList.indexOf((Fragment) object); return position == -1 ? POSITION_NONE : position; diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java index 67de4c2e..b4a0bc76 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/bookmarks/BookmarksFragment.java @@ -23,8 +23,10 @@ import gr.thmmy.mthmmy.model.Bookmark; public class BookmarksFragment extends Fragment { enum Type {TOPIC, BOARD} + private static final String ARG_SECTION_NUMBER = "SECTION_NUMBER"; private static final String ARG_BOOKMARKS = "BOOKMARKS"; + private static final String ARG_CALL_FOR_WIDGET_SETUP = "ARG_CALL_FOR_WIDGET_SETUP"; static final String INTERACTION_CLICK_TOPIC_BOOKMARK = "CLICK_TOPIC_BOOKMARK"; static final String INTERACTION_TOGGLE_TOPIC_NOTIFICATION = "TOGGLE_TOPIC_NOTIFICATION"; @@ -32,9 +34,10 @@ public class BookmarksFragment extends Fragment { static final String INTERACTION_CLICK_BOARD_BOOKMARK = "CLICK_BOARD_BOOKMARK"; static final String INTERACTION_TOGGLE_BOARD_NOTIFICATION = "TOGGLE_BOARD_NOTIFICATION"; - static final String INTERACTION_REMOVE_BOARD_BOOKMARK= "REMOVE_BOARD_BOOKMARK"; + static final String INTERACTION_REMOVE_BOARD_BOOKMARK = "REMOVE_BOARD_BOOKMARK"; private ArrayList bookmarks = null; + private boolean isCalledForWidgetSetup = false; private Type type; private String interactionClick, interactionToggle, interactionRemove; @@ -44,16 +47,15 @@ public class BookmarksFragment extends Fragment { public BookmarksFragment() {/* Required empty public constructor */} private BookmarksFragment(Type type) { - this.type=type; - if(type==Type.TOPIC){ - this.interactionClick=INTERACTION_CLICK_TOPIC_BOOKMARK; - this.interactionToggle=INTERACTION_TOGGLE_TOPIC_NOTIFICATION; - this.interactionRemove=INTERACTION_REMOVE_TOPIC_BOOKMARK; - } - else if (type==Type.BOARD){ - this.interactionClick=INTERACTION_CLICK_BOARD_BOOKMARK; - this.interactionToggle=INTERACTION_TOGGLE_BOARD_NOTIFICATION; - this.interactionRemove=INTERACTION_REMOVE_BOARD_BOOKMARK; + this.type = type; + if (type == Type.TOPIC) { + this.interactionClick = INTERACTION_CLICK_TOPIC_BOOKMARK; + this.interactionToggle = INTERACTION_TOGGLE_TOPIC_NOTIFICATION; + this.interactionRemove = INTERACTION_REMOVE_TOPIC_BOOKMARK; + } else if (type == Type.BOARD) { + this.interactionClick = INTERACTION_CLICK_BOARD_BOOKMARK; + this.interactionToggle = INTERACTION_TOGGLE_BOARD_NOTIFICATION; + this.interactionRemove = INTERACTION_REMOVE_BOARD_BOOKMARK; } } @@ -63,11 +65,13 @@ public class BookmarksFragment extends Fragment { * * @return A new instance of fragment Forum. */ - protected static BookmarksFragment newInstance(int sectionNumber, String bookmarks, Type type) { + protected static BookmarksFragment newInstance(int sectionNumber, String bookmarks, Type type, + boolean isCalledForWidgetSetup) { BookmarksFragment fragment = new BookmarksFragment(type); Bundle args = new Bundle(); args.putInt(ARG_SECTION_NUMBER, sectionNumber); args.putString(ARG_BOOKMARKS, bookmarks); + args.putBoolean(ARG_CALL_FOR_WIDGET_SETUP, isCalledForWidgetSetup); fragment.setArguments(args); return fragment; } @@ -80,6 +84,7 @@ public class BookmarksFragment extends Fragment { if (bundledBookmarks != null) { bookmarks = Bookmark.stringToArrayList(bundledBookmarks); } + isCalledForWidgetSetup = getArguments().getBoolean(ARG_CALL_FOR_WIDGET_SETUP, false); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) @@ -101,7 +106,7 @@ public class BookmarksFragment extends Fragment { //bookmarks container final LinearLayout bookmarksLinearView = rootView.findViewById(R.id.bookmarks_container); - if(this.bookmarks != null && !this.bookmarks.isEmpty()) { + if (this.bookmarks != null && !this.bookmarks.isEmpty()) { for (final Bookmark bookmark : bookmarks) { if (bookmark != null && bookmark.getTitle() != null) { final LinearLayout row = (LinearLayout) layoutInflater.inflate( @@ -114,32 +119,44 @@ public class BookmarksFragment extends Fragment { ((TextView) row.findViewById(R.id.bookmark_title)).setText(bookmark.getTitle()); final ImageButton notificationsEnabledButton = row.findViewById(R.id.toggle_notification); - if (!bookmark.isNotificationsEnabled()) { - notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); - } - - notificationsEnabledButton.setOnClickListener(view -> { - Activity activity = getActivity(); - if (activity instanceof BookmarksActivity) { - if (((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionToggle, bookmark)) - notificationsEnabledButton.setImageDrawable(notificationsEnabledButtonImage); - else - notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); + if (isCalledForWidgetSetup) { + notificationsEnabledButton.setEnabled(false); + notificationsEnabledButton.setVisibility(View.GONE); + } else { + if (!bookmark.isNotificationsEnabled()) { + notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); } - }); - (row.findViewById(R.id.remove_bookmark)).setOnClickListener(view -> { - Activity activity = getActivity(); - if (activity instanceof BookmarksActivity){ - ((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionRemove, bookmark); - bookmarks.remove(bookmark); - } - row.setVisibility(View.GONE); + notificationsEnabledButton.setOnClickListener(view -> { + Activity activity = getActivity(); + if (activity instanceof BookmarksActivity) { + if (((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionToggle, bookmark)) + notificationsEnabledButton.setImageDrawable(notificationsEnabledButtonImage); + else + notificationsEnabledButton.setImageDrawable(notificationsDisabledButtonImage); + } + }); + } + + final ImageButton removeButton = row.findViewById(R.id.remove_bookmark); + if (isCalledForWidgetSetup) { + removeButton.setEnabled(false); + removeButton.setVisibility(View.GONE); + } else { + removeButton.setOnClickListener(view -> { + Activity activity = getActivity(); + if (activity instanceof BookmarksActivity) { + ((BookmarksActivity) activity).onFragmentRowInteractionListener(type, interactionRemove, bookmark); + bookmarks.remove(bookmark); + } + row.setVisibility(View.GONE); + + if (bookmarks.isEmpty()) { + bookmarksLinearView.addView(bookmarksListEmptyMessage()); + } + }); + } - if (bookmarks.isEmpty()){ - bookmarksLinearView.addView(bookmarksListEmptyMessage()); - } - }); bookmarksLinearView.addView(row); } } @@ -155,9 +172,9 @@ public class BookmarksFragment extends Fragment { LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); params.setMargins(0, 12, 0, 0); emptyBookmarksCategory.setLayoutParams(params); - if(type==Type.TOPIC) + if (type == Type.TOPIC) emptyBookmarksCategory.setText(getString(R.string.empty_topic_bookmarks)); - else if(type==Type.BOARD) + else if (type == Type.BOARD) emptyBookmarksCategory.setText(getString(R.string.empty_board_bookmarks)); emptyBookmarksCategory.setTypeface(emptyBookmarksCategory.getTypeface(), Typeface.BOLD); diff --git a/app/src/main/java/gr/thmmy/mthmmy/activities/widget/WidgetProvider.java b/app/src/main/java/gr/thmmy/mthmmy/activities/widget/WidgetProvider.java new file mode 100644 index 00000000..b97618a7 --- /dev/null +++ b/app/src/main/java/gr/thmmy/mthmmy/activities/widget/WidgetProvider.java @@ -0,0 +1,103 @@ +package gr.thmmy.mthmmy.activities.widget; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.View; +import android.widget.RemoteViews; + +import java.util.ArrayList; + +import gr.thmmy.mthmmy.R; +import gr.thmmy.mthmmy.activities.board.BoardActivity; +import gr.thmmy.mthmmy.activities.topic.TopicActivity; +import gr.thmmy.mthmmy.model.Bookmark; + +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_TITLE; +import static gr.thmmy.mthmmy.activities.board.BoardActivity.BUNDLE_BOARD_URL; +import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE; +import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; +import static gr.thmmy.mthmmy.session.SessionManager.boardUrl; +import static gr.thmmy.mthmmy.session.SessionManager.topicUrl; + +public class WidgetProvider extends AppWidgetProvider { + public static final String BOOKMARK_WIDGET_SHARED_PREFS = "bookmarkWidgetSharedPrefs"; + public static final String BOOKMARK_WIDGETS_KEY = "bookmarkWidgetsKey"; + + enum Type {TOPIC, BOARD} + + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // Perform this loop procedure for each App Widget that belongs to this provider + for (int appWidgetId : appWidgetIds) { + updateAppWidget(context, appWidgetManager, appWidgetId, 0); // Todo: check if there are already notifications available + } + } + + public void onDeleted(Context context, int[] appWidgetIds) { + SharedPreferences widgetSharedPrefs = context.getSharedPreferences(BOOKMARK_WIDGET_SHARED_PREFS, Context.MODE_PRIVATE); + SharedPreferences.Editor widgetSharedPrefsEditor = widgetSharedPrefs.edit(); + + for (int appWidgetId : appWidgetIds) { + widgetSharedPrefsEditor.remove(BOOKMARK_WIDGETS_KEY + "_t_" + appWidgetId).remove(BOOKMARK_WIDGETS_KEY + "_b_" + appWidgetId); + } + widgetSharedPrefsEditor.apply(); + } + + public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId, int notifications) { + SharedPreferences widgetSharedPrefs = context.getSharedPreferences(BOOKMARK_WIDGET_SHARED_PREFS, Context.MODE_PRIVATE); + ArrayList tmpArrayList; + + // Gets the bookmark saved in shared prefs + String tmpBookmarkString = widgetSharedPrefs.getString(BOOKMARK_WIDGETS_KEY + "_t_" + appWidgetId, null); + Type type; + + if (tmpBookmarkString != null) { + // It's a topic bookmark + tmpArrayList = Bookmark.stringToArrayList(tmpBookmarkString); + type = Type.TOPIC; + } else { + tmpBookmarkString = widgetSharedPrefs.getString(BOOKMARK_WIDGETS_KEY + "_b_" + appWidgetId, null); + + if (tmpBookmarkString != null) { + // It's a board bookmark + tmpArrayList = Bookmark.stringToArrayList(tmpBookmarkString); + type = Type.BOARD; + } else { + // Error? TODO: Log on Timber + return; + } + } + + // Creates an Intent to launch TopicActivity + Intent intent; + Bundle extras = new Bundle(); + if (type == Type.TOPIC) { + intent = new Intent(context, TopicActivity.class); + extras.putString(BUNDLE_TOPIC_URL, topicUrl + tmpArrayList.get(0).getId() + "." + 2147483647); + extras.putString(BUNDLE_TOPIC_TITLE, tmpArrayList.get(0).getTitle()); + } else { + intent = new Intent(context, BoardActivity.class); + extras.putString(BUNDLE_BOARD_URL, boardUrl + tmpArrayList.get(0).getId() + ".0"); + extras.putString(BUNDLE_BOARD_TITLE, tmpArrayList.get(0).getTitle()); + } + intent.putExtras(extras); + PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); + + // Gets the layout for the Topic Widget and attach an on-click listener to the button + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); + views.setOnClickPendingIntent(R.id.widget_button, pendingIntent); + if (notifications > 0) { + views.setViewVisibility(R.id.widget_notifications_number, View.VISIBLE); + views.setTextViewText(R.id.widget_notifications_number, "" + notifications); + } else { + views.setViewVisibility(R.id.widget_notifications_number, View.GONE); + } + + // Tells the AppWidgetManager to perform an update on the current app widget + appWidgetManager.updateAppWidget(appWidgetId, views); + } +} diff --git a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java index 1da43458..68090b7e 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java +++ b/app/src/main/java/gr/thmmy/mthmmy/model/Bookmark.java @@ -70,15 +70,15 @@ public class Bookmark implements java.io.Serializable { @Nullable public static String arrayListToString(@NonNull ArrayList arrayList) { - String returnString = ""; + StringBuilder returnString = new StringBuilder(); for (Bookmark bookmark : arrayList) { if (bookmark != null) { - returnString += (bookmark.getId() + "\t"); - returnString += (bookmark.getTitle() + "\t"); - returnString += (bookmark.isNotificationsEnabled() + "\n"); + returnString.append(bookmark.getId()).append("\t"); + returnString.append(bookmark.getTitle()).append("\t"); + returnString.append(bookmark.isNotificationsEnabled()).append("\n"); } } - if (!Objects.equals(returnString, "")) return returnString; + if (!Objects.equals(returnString.toString(), "")) return returnString.toString(); else return null; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java index 4e91bc72..d80458cd 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java +++ b/app/src/main/java/gr/thmmy/mthmmy/session/SessionManager.java @@ -39,6 +39,8 @@ public class SessionManager { private static final HttpUrl loginUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=login2"); public static final HttpUrl unreadUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=unread;all;start=0;theme=4"); public static final HttpUrl shoutboxUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?action=tpmod;sa=shoutbox;theme=4"); + public static final HttpUrl topicUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?topic="); + public static final HttpUrl boardUrl = HttpUrl.parse("https://www.thmmy.gr/smf/index.php?board="); private static final String guestName = "Guest"; //Response Codes diff --git a/app/src/main/res/layout/widget.xml b/app/src/main/res/layout/widget.xml new file mode 100644 index 00000000..f43ba11d --- /dev/null +++ b/app/src/main/res/layout/widget.xml @@ -0,0 +1,38 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1593d8ae..881a897f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -232,4 +232,7 @@ New topic Create topic URL copied + + + Topic widget diff --git a/app/src/main/res/xml/widget_info.xml b/app/src/main/res/xml/widget_info.xml new file mode 100644 index 00000000..a338b527 --- /dev/null +++ b/app/src/main/res/xml/widget_info.xml @@ -0,0 +1,10 @@ + +