diff options
author | Stefan Niedermann <info@niedermann.it> | 2021-03-08 12:06:51 +0300 |
---|---|---|
committer | Stefan Niedermann <info@niedermann.it> | 2021-03-08 12:06:51 +0300 |
commit | 9a801eb72da400a7dfbd944386fbd915861a428a (patch) | |
tree | 148ed973563f61ff953b80bb46ebcdea000a5d83 | |
parent | a6cbca60760fcdb502b96a3a53a620d559727df0 (diff) | |
parent | 6e40d1c037420474407bdc0c294e418bf2afce74 (diff) |
Merge branch '767-rewrite-stack-widget'
14 files changed, 247 insertions, 171 deletions
diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/EWidgetType.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/EWidgetType.java index 9f2f93a89..6121c7515 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/EWidgetType.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/EWidgetType.java @@ -1,11 +1,13 @@ package it.niedermann.nextcloud.deck.model.widget.filter; import it.niedermann.nextcloud.deck.ui.widget.filter.FilterWidget; +import it.niedermann.nextcloud.deck.ui.widget.stack.StackWidget; import it.niedermann.nextcloud.deck.ui.widget.upcoming.UpcomingWidget; public enum EWidgetType { FILTER_WIDGET(1, FilterWidget.class), - UPCOMING_WIDGET(2, UpcomingWidget.class); + UPCOMING_WIDGET(2, UpcomingWidget.class), + STACK_WIDGET(3, StackWidget.class); private final int id; private final Class<?> widgetClass; diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetBoard.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetBoard.java index d2f1d24fe..b1697f9b7 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetBoard.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetBoard.java @@ -37,6 +37,16 @@ public class FilterWidgetBoard { private Long boardId; private boolean includeNoLabel = true; + public FilterWidgetBoard() { + // Default constructor + } + + @Ignore + public FilterWidgetBoard(Long boardId, List<FilterWidgetStack> stacks) { + this.boardId = boardId; + this.stacks = stacks; + } + @Ignore private List<FilterWidgetStack> stacks = new ArrayList<>(); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetStack.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetStack.java index 7933d74ff..2da1c0b79 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetStack.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/widget/filter/FilterWidgetStack.java @@ -2,6 +2,7 @@ package it.niedermann.nextcloud.deck.model.widget.filter; import androidx.room.Entity; import androidx.room.ForeignKey; +import androidx.room.Ignore; import androidx.room.Index; import androidx.room.PrimaryKey; @@ -32,6 +33,15 @@ public class FilterWidgetStack { private Long filterBoardId; private Long stackId; + public FilterWidgetStack() { + // Default constructor + } + + @Ignore + public FilterWidgetStack(Long stackId) { + this.stackId = stackId; + } + public Long getId() { return id; } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java index cc2e6da8c..c80d31c21 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/SyncManager.java @@ -2060,4 +2060,15 @@ public class SyncManager { public static boolean ignoreExceptionOnVoidError(Throwable t) { return t instanceof NullPointerException && "Attempt to invoke interface method 'void io.reactivex.disposables.Disposable.dispose()' on a null object reference".equals(t.getMessage()); } + + @WorkerThread + public Stack getStackDirectly(long stackLocalId) { + return dataBaseAdapter.getStackByLocalIdDirectly(stackLocalId); + } + + @ColorInt + @WorkerThread + public Integer getBoardColorDirectly(long accountId, long localBoardId) { + return dataBaseAdapter.getBoardColorDirectly(accountId, localBoardId); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java index e7f3ac113..e0a84ccec 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DataBaseAdapter.java @@ -5,6 +5,7 @@ import android.content.Context; import android.content.Intent; import androidx.annotation.AnyThread; +import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; @@ -69,7 +70,6 @@ import it.niedermann.nextcloud.deck.model.widget.singlecard.SingleCardWidgetMode import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.LiveDataHelper; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.util.WrappedLiveData; import it.niedermann.nextcloud.deck.ui.widget.singlecard.SingleCardWidget; -import it.niedermann.nextcloud.deck.ui.widget.stack.StackWidget; import static androidx.lifecycle.Transformations.distinctUntilChanged; @@ -635,10 +635,10 @@ public class DataBaseAdapter { markAsEditedIfNeeded(stack, setStatus); db.getStackDao().update(stack); notifyFilterWidgetsAboutChangedEntity(FilterWidget.EChangedEntityType.STACK, stack.getLocalId()); - if (db.getStackWidgetModelDao().containsStackLocalId(stack.getLocalId())) { - DeckLog.info("Notifying " + StackWidget.class.getSimpleName() + " about card changes for \"" + stack.getTitle() + "\""); - StackWidget.notifyDatasetChanged(context); - } +// if (db.getStackWidgetModelDao().containsStackLocalId(stack.getLocalId())) { +// DeckLog.info("Notifying " + StackWidget.class.getSimpleName() + " about card changes for \"" + stack.getTitle() + "\""); +// // FIXME StackWidget.notifyDatasetChanged(context); +// } } @WorkerThread @@ -719,10 +719,10 @@ public class DataBaseAdapter { } private void notifyStackWidgetsIfNeeded(String cardTitle, long... affectedStackIds) { - if (db.getStackWidgetModelDao().containsStackLocalId(affectedStackIds)) { - DeckLog.info("Notifying " + StackWidget.class.getSimpleName() + " about card changes for \"" + cardTitle + "\""); - StackWidget.notifyDatasetChanged(context); - } +// if (db.getStackWidgetModelDao().containsStackLocalId(affectedStackIds)) { +// DeckLog.info("Notifying " + StackWidget.class.getSimpleName() + " about card changes for \"" + cardTitle + "\""); +// // FIXME StackWidget.notifyDatasetChanged(context); +// } } @WorkerThread @@ -1157,11 +1157,12 @@ public class DataBaseAdapter { model.setStackId(stackId); model.setDarkTheme(darkTheme); - db.getStackWidgetModelDao().insert(model); +// db.getStackWidgetModelDao().insert(model); } public StackWidgetModel getStackWidgetModelDirectly(int appWidgetId) { - return db.getStackWidgetModelDao().getStackWidgetByAppWidgetIdDirectly(appWidgetId); +// return db.getStackWidgetModelDao().getStackWidgetByAppWidgetIdDirectly(appWidgetId); + return null; } public int createFilterWidgetDirectly(@NonNull FilterWidget filterWidget) { @@ -1366,7 +1367,7 @@ public class DataBaseAdapter { public void deleteStackWidget(int appWidgetId) { StackWidgetModel model = new StackWidgetModel(); model.setAppWidgetId(appWidgetId); - db.getStackWidgetModelDao().delete(model); +// db.getStackWidgetModelDao().delete(model); } public LiveData<List<Account>> readAccountsForHostWithReadAccessToBoard(String host, long boardRemoteId) { @@ -1438,7 +1439,12 @@ public class DataBaseAdapter { private void notifyAllWidgets() { SingleCardWidget.notifyDatasetChanged(context); - StackWidget.notifyDatasetChanged(context); + /// FIXME StackWidget.notifyDatasetChanged(context); // UpcomingWidget.notifyDatasetChanged(context); } + + @ColorInt + public Integer getBoardColorDirectly(long accountId, long localBoardId) { + return db.getBoardDao().getBoardColorByLocalIdDirectly(accountId, localBoardId); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabase.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabase.java index 874568734..9967dcb51 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabase.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/DeckDatabase.java @@ -1,8 +1,10 @@ package it.niedermann.nextcloud.deck.persistence.sync.adapters.db; +import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; import android.graphics.Color; import androidx.annotation.ColorInt; @@ -33,7 +35,6 @@ import it.niedermann.nextcloud.deck.model.Label; import it.niedermann.nextcloud.deck.model.Permission; import it.niedermann.nextcloud.deck.model.Stack; import it.niedermann.nextcloud.deck.model.User; -import it.niedermann.nextcloud.deck.model.appwidgets.StackWidgetModel; import it.niedermann.nextcloud.deck.model.enums.DBStatus; import it.niedermann.nextcloud.deck.model.ocs.Activity; import it.niedermann.nextcloud.deck.model.ocs.comment.DeckComment; @@ -43,6 +44,7 @@ import it.niedermann.nextcloud.deck.model.ocs.projects.OcsProject; import it.niedermann.nextcloud.deck.model.ocs.projects.OcsProjectResource; import it.niedermann.nextcloud.deck.model.relations.UserInBoard; import it.niedermann.nextcloud.deck.model.relations.UserInGroup; +import it.niedermann.nextcloud.deck.model.widget.filter.EWidgetType; import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetAccount; import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetBoard; @@ -78,7 +80,6 @@ import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.projects.Jo import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.projects.OcsProjectDao; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.projects.OcsProjectResourceDao; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.SingleCardWidgetModelDao; -import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.StackWidgetModelDao; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.filter.FilterWidgetAccountDao; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.filter.FilterWidgetBoardDao; import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.filter.FilterWidgetDao; @@ -108,7 +109,6 @@ import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.fil DeckComment.class, Mention.class, SingleCardWidgetModel.class, - StackWidgetModel.class, OcsProject.class, OcsProjectResource.class, JoinCardWithProject.class, @@ -125,7 +125,7 @@ import it.niedermann.nextcloud.deck.persistence.sync.adapters.db.dao.widgets.fil FilterWidgetSort.class, }, exportSchema = false, - version = 26 + version = 27 ) @TypeConverters({DateTypeConverter.class, EnumConverter.class}) public abstract class DeckDatabase extends RoomDatabase { @@ -461,6 +461,51 @@ public abstract class DeckDatabase extends RoomDatabase { } }; + private static final Migration MIGRATION_26_27 = new Migration(26, 27) { + @Override + public void migrate(SupportSQLiteDatabase database) { + + Cursor cursor = database.query("select s.localId, s.boardId, s.accountId, w.appWidgetId from `StackWidgetModel` w inner join `Stack` s on s.localId = w.stackId"); + while (cursor.moveToNext()) { + Long localStackId = cursor.getLong(0); + Long localBoardId = cursor.getLong(1); + Long accountId = cursor.getLong(2); + Long filterWidgetId = cursor.getLong(3); + + // widget: + ContentValues values = new ContentValues(); + values.put("widgetType", EWidgetType.STACK_WIDGET.getId()); + values.put("id", filterWidgetId); + database.insert("FilterWidget", SQLiteDatabase.CONFLICT_NONE, values); + + // account + values = new ContentValues(); + values.put("filterWidgetId", filterWidgetId); + values.put("accountId", accountId); + values.put("includeNoUser", false); + values.put("includeNoProject", false); + long filterWidgetAccountId = database.insert("FilterWidgetAccount", SQLiteDatabase.CONFLICT_NONE, values); + + // board + values = new ContentValues(); + values.put("filterAccountId", filterWidgetAccountId); + values.put("boardId", localBoardId); + values.put("includeNoLabel", false); + long filterWidgetBoardId = database.insert("FilterWidgetBoard", SQLiteDatabase.CONFLICT_NONE, values); + + // stack + values = new ContentValues(); + values.put("filterBoardId", filterWidgetBoardId); + values.put("stackId", localStackId); + database.insert("FilterWidgetStack", SQLiteDatabase.CONFLICT_NONE, values); + + + } + + // cleanup + database.execSQL("DROP TABLE `StackWidgetModel`"); + } + }; public static final RoomDatabase.Callback ON_CREATE_CALLBACK = new RoomDatabase.Callback() { @Override @@ -540,6 +585,7 @@ public abstract class DeckDatabase extends RoomDatabase { }) .addMigrations(MIGRATION_24_25) .addMigrations(MIGRATION_25_26) + .addMigrations(MIGRATION_26_27) .fallbackToDestructiveMigration() .addCallback(ON_CREATE_CALLBACK) .build(); @@ -581,8 +627,6 @@ public abstract class DeckDatabase extends RoomDatabase { public abstract SingleCardWidgetModelDao getSingleCardWidgetModelDao(); - public abstract StackWidgetModelDao getStackWidgetModelDao(); - public abstract OcsProjectDao getOcsProjectDao(); public abstract OcsProjectResourceDao getOcsProjectResourceDao(); diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDao.java b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDao.java index fcb662b1d..89ada6e18 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDao.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/persistence/sync/adapters/db/dao/BoardDao.java @@ -51,7 +51,6 @@ public interface BoardDao extends GenericDao<Board> { @Query("SELECT * FROM board WHERE accountId = :accountId and localId = :localId") LiveData<FullBoard> getFullBoardById(final long accountId, final long localId); - @Query("SELECT b.* FROM board b JOIN stack s ON s.boardId = b.localId JOIN card c ON s.localId = c.stackId where c.localId = :localCardId") Board getBoardByLocalCardIdDirectly(long localCardId); @@ -69,7 +68,6 @@ public interface BoardDao extends GenericDao<Board> { @Query("SELECT * FROM board WHERE accountId = :accountId and archived = 0 and permissionEdit = 1 and (deletedAt = 0 or deletedAt is null) and status <> 3 order by title asc") LiveData<List<Board>> getBoardsWithEditPermissionsForAccount(long accountId); - @Query("SELECT b.localId " + "FROM card c " + "inner join stack s on s.localId = c.stackId " + @@ -82,4 +80,7 @@ public interface BoardDao extends GenericDao<Board> { @Query("SELECT * FROM board WHERE accountId = :accountId and title = :title") Board getBoardForAccountByNameDirectly(long accountId, String title); + + @Query("SELECT b.color FROM board b where b.localId = :localBoardId and b.accountId = :accountId") + Integer getBoardColorByLocalIdDirectly(long accountId, long localBoardId); }
\ No newline at end of file diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetFactory.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetFactory.java index 12b1e78d0..db24afa43 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetFactory.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetFactory.java @@ -10,6 +10,8 @@ import android.widget.RemoteViewsService; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import java.util.NoSuchElementException; + import it.niedermann.android.markdown.MarkdownUtil; import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.model.full.FullSingleCardWidgetModel; @@ -35,7 +37,11 @@ public class SingleCardWidgetFactory implements RemoteViewsService.RemoteViewsFa @Override public void onDataSetChanged() { - this.model = syncManager.getSingleCardWidgetModelDirectly(appWidgetId); + try { + this.model = syncManager.getSingleCardWidgetModelDirectly(appWidgetId); + } catch (NoSuchElementException e) { + this.model = null; + } } @Override diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java index cb179953c..38f592adb 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidget.java @@ -7,14 +7,15 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.net.Uri; -import android.os.Bundle; import android.widget.RemoteViews; -import java.util.NoSuchElementException; +import androidx.annotation.ColorInt; +import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; -import it.niedermann.nextcloud.deck.model.Account; -import it.niedermann.nextcloud.deck.model.appwidgets.StackWidgetModel; +import it.niedermann.nextcloud.deck.api.IResponseCallback; +import it.niedermann.nextcloud.deck.model.Stack; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import it.niedermann.nextcloud.deck.ui.MainActivity; import it.niedermann.nextcloud.deck.ui.card.EditActivity; @@ -22,82 +23,29 @@ import it.niedermann.nextcloud.deck.ui.card.EditActivity; import static android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE; public class StackWidget extends AppWidgetProvider { - public static final String ACCOUNT_ID_KEY = "stack_widget_account_id"; - public static final String ACCOUNT_KEY = "stack_widget_account"; - public static final String STACK_ID_KEY = "stack_widget_stack_id"; - public static final String BUNDLE_KEY = "stack_widget_bundle"; private static final int PENDING_INTENT_OPEN_APP_RQ = 0; private static final int PENDING_INTENT_EDIT_CARD_RQ = 1; - static void updateAppWidget(Context context, AppWidgetManager awm, int[] appWidgetIds, Account account) { - final SyncManager syncManager = new SyncManager(context); - - for (int appWidgetId : appWidgetIds) { - new Thread(() -> { - try { - final StackWidgetModel model = syncManager.getStackWidgetModelDirectly(appWidgetId); - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_stack); - Intent serviceIntent = new Intent(context, StackWidgetService.class); - - serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - serviceIntent.putExtra(ACCOUNT_ID_KEY + appWidgetId, model.getAccountId()); - serviceIntent.putExtra(STACK_ID_KEY + appWidgetId, model.getStackId()); - if (account != null) { - Bundle extras = new Bundle(); - extras.putSerializable(StackWidget.ACCOUNT_KEY + appWidgetId, account); - serviceIntent.putExtra(BUNDLE_KEY + appWidgetId, extras); - } - serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); - - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.setComponent(new ComponentName(context.getPackageName(), MainActivity.class.getName())); - PendingIntent pendingIntent = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_APP_RQ, - intent, PendingIntent.FLAG_UPDATE_CURRENT); - views.setOnClickPendingIntent(R.id.widget_stack_header_rl, pendingIntent); - - PendingIntent templatePI = PendingIntent.getActivity(context, PENDING_INTENT_EDIT_CARD_RQ, - new Intent(context, EditActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); - - views.setPendingIntentTemplate(R.id.stack_widget_lv, templatePI); - views.setRemoteAdapter(R.id.stack_widget_lv, serviceIntent); - views.setEmptyView(R.id.stack_widget_lv, R.id.widget_stack_placeholder_iv); - awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.stack_widget_lv); - awm.updateAppWidget(appWidgetId, views); - } catch (NoSuchElementException e) { - // onUpdate has been triggered before the user finished configuring the widget - } - }).start(); - } - } - @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); - updateAppWidget(context, appWidgetManager, appWidgetIds, null); + updateAppWidget(context, appWidgetManager, appWidgetIds); } @Override public void onReceive(Context context, Intent intent) { - final Account account; - super.onReceive(context, intent); - AppWidgetManager awm = AppWidgetManager.getInstance(context); - - if (intent.getAction() != null) { - if (intent.getAction().equals(ACTION_APPWIDGET_UPDATE)) { - if (intent.hasExtra(BUNDLE_KEY)) { - Bundle extras = intent.getBundleExtra(StackWidget.BUNDLE_KEY); - account = (Account) extras.getSerializable(ACCOUNT_KEY); + final AppWidgetManager awm = AppWidgetManager.getInstance(context); - if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { - if (intent.getExtras() != null) { - updateAppWidget(context, awm, new int[]{intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1)}, account); - } - } else { - updateAppWidget(context, awm, awm.getAppWidgetIds(new ComponentName(context, StackWidget.class)), account); - } - } + if (ACTION_APPWIDGET_UPDATE.equals(intent.getAction())) { + if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { + final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); + DeckLog.verbose(ACTION_APPWIDGET_UPDATE + " for " + StackWidget.class.getSimpleName() + " with id " + appWidgetId + ", perform update."); + updateAppWidget(context, awm, new int[]{appWidgetId}); + } else { + DeckLog.verbose(ACTION_APPWIDGET_UPDATE + " for " + StackWidget.class.getSimpleName() + ": Triggering update for all widgets of this type."); + updateAppWidget(context, awm, awm.getAppWidgetIds(new ComponentName(context, StackWidget.class))); } } } @@ -108,14 +56,55 @@ public class StackWidget extends AppWidgetProvider { final SyncManager syncManager = new SyncManager(context); for (int appWidgetId : appWidgetIds) { - syncManager.deleteStackWidgetModel(appWidgetId); + DeckLog.info("Delete " + StackWidget.class.getSimpleName() + " with id " + appWidgetId); + syncManager.deleteFilterWidget(appWidgetId, new IResponseCallback<Boolean>(null) { + @Override + public void onResponse(Boolean response) { + DeckLog.verbose("Successfully deleted " + StackWidget.class.getSimpleName() + " with id " + appWidgetId); + } + }); } } - /** - * Updates UI data of all {@link StackWidget} instances - */ - public static void notifyDatasetChanged(Context context) { - context.sendBroadcast(new Intent(context, StackWidget.class).setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE)); + private static void updateAppWidget(Context context, AppWidgetManager awm, int[] appWidgetIds) { + final SyncManager syncManager = new SyncManager(context); + for (int appWidgetId : appWidgetIds) { + new Thread(() -> { + if (syncManager.filterWidgetExists(appWidgetId)) { + final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_stack); + + final Intent serviceIntent = new Intent(context, StackWidgetService.class); + serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); + + final Intent intent = new Intent(Intent.ACTION_MAIN).setComponent(new ComponentName(context.getPackageName(), MainActivity.class.getName())); + final PendingIntent pendingIntent = PendingIntent.getActivity(context, PENDING_INTENT_OPEN_APP_RQ, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + final PendingIntent templatePI = PendingIntent.getActivity(context, PENDING_INTENT_EDIT_CARD_RQ, + new Intent(context, EditActivity.class), PendingIntent.FLAG_UPDATE_CURRENT); + + views.setOnClickPendingIntent(R.id.widget_stack_header_rl, pendingIntent); + + views.setPendingIntentTemplate(R.id.stack_widget_lv, templatePI); + views.setRemoteAdapter(R.id.stack_widget_lv, serviceIntent); + views.setEmptyView(R.id.stack_widget_lv, R.id.widget_stack_placeholder_iv); + + syncManager.getFilterWidget(appWidgetId, new IResponseCallback<FilterWidget>(null) { + @Override + public void onResponse(FilterWidget response) { + final Stack stack = syncManager.getStackDirectly(response.getAccounts().get(0).getBoards().get(0).getStacks().get(0).getStackId()); + @ColorInt final Integer boardColor = syncManager.getBoardColorDirectly(response.getAccounts().get(0).getAccountId(), response.getAccounts().get(0).getBoards().get(0).getBoardId()); + views.setTextViewText(R.id.widget_stack_title_tv, stack.getTitle()); + views.setInt(R.id.widget_stack_header_icon, "setColorFilter", boardColor); + + awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.stack_widget_lv); + awm.updateAppWidget(appWidgetId, views); + } + }); + } else { + DeckLog.warn("Does not yet exist"); + } + }).start(); + } } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationActivity.java index 96b5cf672..a34123e29 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationActivity.java @@ -7,10 +7,19 @@ import android.os.Bundle; import androidx.appcompat.app.ActionBar; import androidx.lifecycle.ViewModelProvider; +import java.util.Collections; + import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.model.Account; +import it.niedermann.nextcloud.deck.model.widget.filter.EWidgetType; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetAccount; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetBoard; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidgetStack; import it.niedermann.nextcloud.deck.ui.PickStackActivity; +import it.niedermann.nextcloud.deck.ui.exception.ExceptionDialogFragment; public class StackWidgetConfigurationActivity extends PickStackActivity { private int appWidgetId; @@ -43,22 +52,35 @@ public class StackWidgetConfigurationActivity extends PickStackActivity { @Override protected void onSubmit(Account account, long boardId, long stackId) { - final Bundle extras = new Bundle(); - - stackWidgetConfigurationViewModel.addStackWidget(appWidgetId, account.getId(), stackId, false); - Intent updateIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, - getApplicationContext(), StackWidget.class); - extras.putSerializable(StackWidget.ACCOUNT_KEY, account); - extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - - // The `extras` bundle is added to the intent this way because using putExtras(extras) - // would have the OS attempt to reassemle the data and cause a crash - // when it finds classes that are only known to this application. - updateIntent.putExtra(StackWidget.BUNDLE_KEY, extras); - setResult(RESULT_OK, updateIntent); - getApplicationContext().sendBroadcast(updateIntent); - - finish(); + final FilterWidget config = new FilterWidget(appWidgetId, EWidgetType.STACK_WIDGET); + final FilterWidgetAccount filterWidgetAccount = new FilterWidgetAccount(account.getId(), false); + filterWidgetAccount.setIncludeNoProject(false); + FilterWidgetBoard filterWidgetBoard = new FilterWidgetBoard(boardId, Collections.singletonList(new FilterWidgetStack(stackId))); + filterWidgetBoard.setIncludeNoLabel(false); + filterWidgetAccount.setBoards( + Collections.singletonList(filterWidgetBoard)); + config.setAccounts(Collections.singletonList(filterWidgetAccount)); + stackWidgetConfigurationViewModel.addStackWidget(config, new IResponseCallback<Integer>(account) { + + @Override + public void onResponse(Integer response) { + final Intent updateIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, + getApplicationContext(), StackWidget.class) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + setResult(RESULT_OK, updateIntent); + getApplicationContext().sendBroadcast(updateIntent); + + finish(); + } + + @Override + public void onError(Throwable throwable) { + super.onError(throwable); + ExceptionDialogFragment + .newInstance(throwable, account) + .show(getSupportFragmentManager(), ExceptionDialogFragment.class.getSimpleName()); + } + }); } @Override diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationViewModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationViewModel.java index cc669accf..54ae5635e 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationViewModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetConfigurationViewModel.java @@ -5,6 +5,8 @@ import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; +import it.niedermann.nextcloud.deck.api.IResponseCallback; +import it.niedermann.nextcloud.deck.model.widget.filter.FilterWidget; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; @SuppressWarnings("WeakerAccess") @@ -17,7 +19,7 @@ public class StackWidgetConfigurationViewModel extends AndroidViewModel { this.syncManager = new SyncManager(application); } - public void addStackWidget(int appWidgetId, long accountId, long stackId, boolean darkTheme) { - syncManager.addStackWidget(appWidgetId, accountId, stackId, darkTheme); + public void addStackWidget(@NonNull FilterWidget config, @NonNull IResponseCallback<Integer> callback) { + syncManager.createFilterWidget(config, callback); } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetFactory.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetFactory.java index 87f357e20..0ee8877f5 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetFactory.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/stack/StackWidgetFactory.java @@ -1,76 +1,58 @@ package it.niedermann.nextcloud.deck.ui.widget.stack; import android.appwidget.AppWidgetManager; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.widget.RemoteViews; import android.widget.RemoteViewsService; -import androidx.lifecycle.LiveData; +import androidx.annotation.NonNull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; +import java.util.NoSuchElementException; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; -import it.niedermann.nextcloud.deck.model.Account; -import it.niedermann.nextcloud.deck.model.full.FullBoard; -import it.niedermann.nextcloud.deck.model.full.FullCard; -import it.niedermann.nextcloud.deck.model.full.FullStack; +import it.niedermann.nextcloud.deck.model.widget.filter.dto.FilterWidgetCard; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import it.niedermann.nextcloud.deck.ui.card.EditActivity; public class StackWidgetFactory implements RemoteViewsService.RemoteViewsFactory { private final Context context; private final int appWidgetId; - private final long accountId; - private final long stackId; + private final SyncManager syncManager; - private Account account; - private FullStack stack; - private List<FullCard> cardList; + @NonNull + private final List<FilterWidgetCard> data = new ArrayList<>(); StackWidgetFactory(Context context, Intent intent) { this.context = context; appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); - accountId = intent.getLongExtra(StackWidget.ACCOUNT_ID_KEY + appWidgetId, -1); - stackId = intent.getLongExtra(StackWidget.STACK_ID_KEY + appWidgetId, -1); - if (intent.hasExtra(StackWidget.BUNDLE_KEY + appWidgetId)) { - account = (Account) intent.getBundleExtra(StackWidget.BUNDLE_KEY + appWidgetId).getSerializable(StackWidget.ACCOUNT_KEY + appWidgetId); - } + this.syncManager = new SyncManager(context); } @Override public void onCreate() { - SyncManager syncManager = new SyncManager(context); - - LiveData<FullStack> stackLiveData = syncManager.getStack(accountId, stackId); - stackLiveData.observeForever((FullStack fullStack) -> { - if (fullStack != null) { - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_stack); - stack = fullStack; - views.setTextViewText(R.id.widget_stack_title_tv, stack.getStack().getTitle()); - - LiveData<FullBoard> fullBoardLiveData = syncManager.getFullBoardById(accountId, stack.getStack().getBoardId()); - fullBoardLiveData.observeForever((FullBoard fullBoard) -> { - if (fullBoard != null) { - views.setInt(R.id.widget_stack_header_icon, "setColorFilter", fullBoard.getBoard().getColor()); - notifyAppWidgetUpdate(views); - } - }); - - LiveData<List<FullCard>> fullCardData = syncManager.getFullCardsForStack(accountId, stackId, null); - fullCardData.observeForever((List<FullCard> fullCards) -> cardList = fullCards); - notifyAppWidgetUpdate(views); - } - }); + // Nothing to do here... } @Override public void onDataSetChanged() { - + try { + final List<FilterWidgetCard> response = syncManager.getCardsForFilterWidget(appWidgetId); + DeckLog.verbose(StackWidget.class.getSimpleName() + " with id " + appWidgetId + " fetched " + response.size() + " cards from the database."); + data.clear(); + Collections.sort(response, Comparator.comparingLong(value -> value.getCard().getCard().getOrder())); + data.addAll(response); + } catch (NoSuchElementException e) { + DeckLog.error("No " + StackWidget.class.getSimpleName() + " for appWidgetId " + appWidgetId + " found."); + DeckLog.logError(e); + } } @@ -81,24 +63,22 @@ public class StackWidgetFactory implements RemoteViewsService.RemoteViewsFactory @Override public int getCount() { - return stack == null ? 0 : stack.getCards().size(); + return data.size(); } @Override public RemoteViews getViewAt(int i) { - RemoteViews widget_entry; - - if (cardList == null || i > (cardList.size() - 1) || cardList.get(i) == null) { - DeckLog.error("Card not found at position " + i); + if (i > (data.size() - 1) || data.get(i) == null) { + DeckLog.error("No card or separator not found at position " + i); return null; } - - FullCard card = cardList.get(i); + final RemoteViews widget_entry; + final FilterWidgetCard filterWidgetCard = data.get(i); widget_entry = new RemoteViews(context.getPackageName(), R.layout.widget_stack_entry); - widget_entry.setTextViewText(R.id.widget_entry_content_tv, card.card.getTitle()); + widget_entry.setTextViewText(R.id.widget_entry_content_tv, filterWidgetCard.getCard().getCard().getTitle()); - final Intent intent = EditActivity.createEditCardIntent(context, account, stack.getStack().getBoardId(), card.getCard().getLocalId()); + final Intent intent = EditActivity.createEditCardIntent(context, syncManager.readAccountDirectly(filterWidgetCard.getCard().getAccountId()), filterWidgetCard.getStack().getBoardId(), filterWidgetCard.getCard().getLocalId()); intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); widget_entry.setOnClickFillInIntent(R.id.widget_stack_entry, intent); @@ -124,11 +104,4 @@ public class StackWidgetFactory implements RemoteViewsService.RemoteViewsFactory public boolean hasStableIds() { return true; } - - private void notifyAppWidgetUpdate(RemoteViews views) { - AppWidgetManager awm = AppWidgetManager.getInstance(context); - int[] appWidgetIds = awm.getAppWidgetIds(new ComponentName(context, StackWidget.class)); - awm.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.stack_widget_lv); - awm.updateAppWidget(appWidgetId, views); - } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java index 0cd668722..480b8e9c1 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidget.java @@ -79,7 +79,7 @@ public class UpcomingWidget extends AppWidgetProvider { if (ACTION_APPWIDGET_UPDATE.equals(intent.getAction())) { if (intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) { - int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); + final int appWidgetId = intent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); DeckLog.verbose(ACTION_APPWIDGET_UPDATE + " for " + UpcomingWidget.class.getSimpleName() + " with id " + appWidgetId + ", perform update."); updateAppWidget(context, awm, new int[]{appWidgetId}); } else { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidgetFactory.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidgetFactory.java index 97f2cbe48..ae8aca30f 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidgetFactory.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/upcoming/UpcomingWidgetFactory.java @@ -55,7 +55,7 @@ public class UpcomingWidgetFactory implements RemoteViewsService.RemoteViewsFact final List<FilterWidgetCard> response = syncManager.getCardsForFilterWidget(appWidgetId); DeckLog.verbose(UpcomingWidgetFactory.class.getSimpleName() + " with id " + appWidgetId + " fetched " + response.size() + " cards from the database."); data.clear(); - Comparator<FilterWidgetCard> comparator = Comparator.comparing((card -> { + final Comparator<FilterWidgetCard> comparator = Comparator.comparing((card -> { if (card != null && card.getCard() != null && card.getCard().getCard() != null && |