diff options
10 files changed, 146 insertions, 164 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0d45e2c44..d81c47fd3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -133,6 +133,20 @@ <action android:name="android.service.quicksettings.action.QS_TILE" /> </intent-filter> </service> - </application> + + <activity + android:name=".ui.widget.singlecard.SelectCardForWidgetActivity" + android:label="@string/share_add_to_card" + android:theme="@style/SplashTheme" /> + + <receiver android:name=".ui.widget.singlecard.SingleCardWidget"> + <intent-filter> + <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> + </intent-filter> + <meta-data + android:name="android.appwidget.provider" + android:resource="@xml/widget_single_card_info" /> + </receiver> + </application> </manifest> diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/model/SingleCardWidgetModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/model/SingleCardWidgetModel.java index 3912159d4..4c7a09ea5 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/model/SingleCardWidgetModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/model/SingleCardWidgetModel.java @@ -33,11 +33,12 @@ public class SingleCardWidgetModel { this.boardLocalId = boardLocalId; } - public FullCard getCardLocalId() { + public FullCard getFullCard() { return fullCard; } public void setCardLocalId(FullCard cardLocalId) { this.fullCard = cardLocalId; } + } 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 b2fef5217..ed5d882b5 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 @@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteConstraintException; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.WorkerThread; import androidx.core.util.Pair; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; @@ -16,6 +17,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.NoSuchElementException; import java.util.concurrent.CountDownLatch; import it.niedermann.nextcloud.deck.DeckLog; @@ -1285,20 +1287,26 @@ public class SyncManager { // Widgets // ------------------- - public void addSingleCardWidget(long id, long accountId, long boardId, long localCardId) { - // TODO implement + /** + * Can be called from a configuration screen or a picker. + * Creates a new entry in the database, if row with given widgetId does not yet exist. + */ + public void addOrUpdateSingleCardWidget(int widgetId, long accountId, long boardId, long localCardId) { + // TODO implement async } - public WrappedLiveData<SingleCardWidgetModel> getSingleCardWidgetModel(long id) { - // TODO implement - WrappedLiveData<SingleCardWidgetModel> modelLiveData = new WrappedLiveData<>(); - SingleCardWidgetModel model = new SingleCardWidgetModel(); - modelLiveData.postValue(model); - return modelLiveData; + @WorkerThread + public SingleCardWidgetModel getSingleCardWidgetModelDirectly(int widgetId) throws NoSuchElementException { + // TODO if widgetId not found throw NoSuchElementException + throw new NoSuchElementException(); + // TODO else grab data and put it into model, return model + // SingleCardWidgetModel model = new SingleCardWidgetModel(); + // return model; } - public void deleteSingleCardWidgetModel(long id) { - // TODO implement + @WorkerThread + public void deleteSingleCardWidgetModel(int widgetId) { + // TODO implement synchronous } private static class BooleanResultHolder { 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 4364c093d..ae3fef8a4 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 @@ -36,6 +36,7 @@ import it.niedermann.nextcloud.deck.model.ocs.comment.DeckComment; import it.niedermann.nextcloud.deck.model.ocs.comment.Mention; 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 static androidx.lifecycle.Transformations.distinctUntilChanged; @@ -487,6 +488,7 @@ public class DataBaseAdapter { public void updateCard(Card card, boolean setStatus) { markAsEditedIfNeeded(card, setStatus); db.getCardDao().update(card); + SingleCardWidget.notifyDatasetChanged(context); } public long createAccessControl(long accountId, AccessControl entity) { diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java new file mode 100644 index 000000000..e87e9c955 --- /dev/null +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SelectCardForWidgetActivity.java @@ -0,0 +1,67 @@ +package it.niedermann.nextcloud.deck.ui.widget.singlecard; + +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.os.Bundle; +import android.view.Menu; +import android.view.View; + +import androidx.annotation.NonNull; + +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.Board; +import it.niedermann.nextcloud.deck.model.full.FullCard; +import it.niedermann.nextcloud.deck.ui.MainActivity; +import it.niedermann.nextcloud.deck.ui.card.SelectCardListener; + +public class SelectCardForWidgetActivity extends MainActivity implements SelectCardListener { + + private int appWidgetId; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final Intent intent = getIntent(); + if (intent == null) { + finish(); + return; + } + final Bundle args = intent.getExtras(); + if (args == null) { + finish(); + return; + } + appWidgetId = args.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { + finish(); + } + } + + @Override + public void onCardSelected(FullCard fullCard) { + syncManager.addOrUpdateSingleCardWidget(appWidgetId, mainViewModel.getCurrentAccount().getId(), mainViewModel.getCurrentBoardLocalId(), fullCard.getLocalId()); + final Intent updateIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, + getApplicationContext(), SingleCardWidget.class) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + setResult(RESULT_OK, updateIntent); + getApplicationContext().sendBroadcast(updateIntent); + finish(); + } + + @Override + protected void setCurrentBoard(@NonNull Board board) { + super.setCurrentBoard(board); + binding.addStackButton.setVisibility(View.GONE); + binding.fab.setVisibility(View.GONE); + binding.toolbar.setTitle(R.string.simple_select); + } + + @Override + protected void showFabIfEditPermissionGranted() { /* Silence is gold */ } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + +} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java index cba5e5fdb..758debe10 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidget.java @@ -6,12 +6,18 @@ import android.appwidget.AppWidgetProvider; import android.content.ComponentName; import android.content.Context; import android.content.Intent; -import android.net.Uri; import android.widget.RemoteViews; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.NoSuchElementException; + +import it.niedermann.nextcloud.deck.R; +import it.niedermann.nextcloud.deck.model.SingleCardWidgetModel; import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; import it.niedermann.nextcloud.deck.ui.card.EditActivity; -import it.niedermann.owncloud.notes.R; public class SingleCardWidget extends AppWidgetProvider { @@ -19,26 +25,23 @@ public class SingleCardWidget extends AppWidgetProvider { final SyncManager syncManager = new SyncManager(context); for (int appWidgetId : appWidgetIds) { - syncManager.getSingleCardWidgetModel(appWidgetId).observe(this, (model) -> { - - Intent templateIntent = EditActivity.createEditCardIntent(context, model.getAccount(), model.getBoardLocalId(), model.getCardLocalId()); - - PendingIntent templatePendingIntent = PendingIntent.getActivity(context, appWidgetId, templateIntent, - PendingIntent.FLAG_UPDATE_CURRENT); + try { + final SingleCardWidgetModel model = syncManager.getSingleCardWidgetModelDirectly(appWidgetId); - Intent serviceIntent = new Intent(context, SingleCardWidgetService.class); - serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); - serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); + Intent intent = EditActivity.createEditCardIntent(context, model.getAccount(), model.getBoardLocalId(), model.getFullCard().getLocalId()); + PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT); - RemoteViews views; + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_single_card); + views.setOnClickPendingIntent(R.id.title, pendingIntent); - views = new RemoteViews(context.getPackageName(), R.layout.widget_single_note); - views.setPendingIntentTemplate(R.id.single_note_widget_lv, templatePendingIntent); - views.setRemoteAdapter(R.id.single_note_widget_lv, serviceIntent); - views.setEmptyView(R.id.single_note_widget_lv, R.id.widget_single_note_placeholder_tv); - awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.single_note_widget_lv); + DateFormat format = SimpleDateFormat.getTimeInstance( + SimpleDateFormat.MEDIUM, Locale.getDefault()); + CharSequence text = format.format(new Date()); + views.setTextViewText(R.id.title, "My Widget Homie " + text); awm.updateAppWidget(appWidgetId, views); - }); + } catch (NoSuchElementException e) { + // onUpdate has been triggered before the user finished configuring the widget + } } } @@ -67,4 +70,14 @@ public class SingleCardWidget extends AppWidgetProvider { super.onDeleted(context, appWidgetIds); } + + + /** + * Updates UI data of all {@link SingleCardWidget} instances + */ + public static void notifyDatasetChanged(Context context) { + Intent intent = new Intent(context, SingleCardWidget.class); + intent.setAction("android.appwidget.action.APPWIDGET_UPDATE"); + context.sendBroadcast(intent); + } } 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 deleted file mode 100644 index 9ca6d476a..000000000 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetFactory.java +++ /dev/null @@ -1,123 +0,0 @@ -package it.niedermann.nextcloud.deck.ui.widget.singlecard; - -import android.appwidget.AppWidgetManager; -import android.content.Context; -import android.content.Intent; -import android.util.Log; -import android.widget.RemoteViews; -import android.widget.RemoteViewsService; - -import it.niedermann.nextcloud.deck.model.SingleCardWidgetModel; -import it.niedermann.nextcloud.deck.persistence.sync.SyncManager; -import it.niedermann.nextcloud.deck.ui.card.EditActivity; -import it.niedermann.owncloud.notes.R; - -public class SingleCardWidgetFactory implements RemoteViewsService.RemoteViewsFactory { - - private final Context context; - private final int appWidgetId; - - private SyncManager syncManager; - private SingleCardWidgetModel singleCardWidgetModel; - - private static final String TAG = SingleCardWidget.class.getSimpleName(); - - SingleCardWidgetFactory(Context context, Intent intent) { - this.context = context; - appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); - } - - @Override - public void onCreate() { - syncManager = new SyncManager(context); - } - - - @Override - public void onDataSetChanged() { - syncManager.getSingleCardWidgetModel(appWidgetId).observe(this, (model) -> { - long noteID = sp.getLong(SingleCardWidget.WIDGET_KEY + appWidgetId, -1); - - if (noteID >= 0) { - Log.v(TAG, "Fetch note for account " + SingleCardWidget.ACCOUNT_ID_KEY + appWidgetId); - Log.v(TAG, "Fetch note for account " + sp.getLong(SingleCardWidget.ACCOUNT_ID_KEY + appWidgetId, -1)); - Log.v(TAG, "Fetch note with id " + noteID); - singleCardWidgetModel = syncManager.getNote(sp.getLong(SingleCardWidget.ACCOUNT_ID_KEY + appWidgetId, -1), noteID); - - if (singleCardWidgetModel == null) { - Log.e(TAG, "Error: note not found"); - } - } - }); - } - - @Override - public void onDestroy() { - //NoOp - } - - /** - * Returns the number of items in the data set. In this case, always 1 as a single note is - * being displayed. Will return 0 when the note can't be displayed. - */ - @Override - public int getCount() { - return (singleCardWidgetModel != null) ? 1 : 0; - } - - /** - * Returns a RemoteView containing the note content in a TextView and - * a fillInIntent to handle the user tapping on the item in the list view. - * - * @param position The position of the item in the list - * @return The RemoteView at the specified position in the list - */ - @Override - public RemoteViews getViewAt(int position) { - if (singleCardWidgetModel == null) { - return null; - } - long noteID = sp.getLong(SingleCardWidget.WIDGET_KEY + appWidgetId, -1); - - if (noteID >= 0) { - Log.v(TAG, "Fetch note for account " + SingleCardWidget.ACCOUNT_ID_KEY + appWidgetId); - Log.v(TAG, "Fetch note for account " + sp.getLong(SingleCardWidget.ACCOUNT_ID_KEY + appWidgetId, -1)); - Log.v(TAG, "Fetch note with id " + noteID); - singleCardWidgetModel = syncManager.getNote(sp.getLong(SingleCardWidget.ACCOUNT_ID_KEY + appWidgetId, -1), noteID); - - if (singleCardWidgetModel == null) { - Log.e(TAG, "Error: note not found"); - } - } - - RemoteViews widgetRemoteView; - final Intent fillInIntent = EditActivity.createEditCardIntent(context, singleCardWidgetModel.getAccount(), singleCardWidgetModel.getBoardLocalId(), singleCardWidgetModel.getCardLocalId().getLocalId()); - widgetRemoteView = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); - widgetRemoteView.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); - widgetRemoteView.setTextViewText(R.id.single_note_content_tv, singleCardWidgetModel.getCardLocalId().getCard().getTitle()); - - return widgetRemoteView; - } - - - // TODO Set loading view - @Override - public RemoteViews getLoadingView() { - return null; - } - - @Override - public int getViewTypeCount() { - return 1; - } - - @Override - public long getItemId(int position) { - return position; - } - - @Override - public boolean hasStableIds() { - return true; - } -} diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetService.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetService.java deleted file mode 100644 index d938e383a..000000000 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/widget/singlecard/SingleCardWidgetService.java +++ /dev/null @@ -1,11 +0,0 @@ -package it.niedermann.nextcloud.deck.ui.widget.singlecard; - -import android.content.Intent; -import android.widget.RemoteViewsService; - -public class SingleCardWidgetService extends RemoteViewsService { - @Override - public RemoteViewsFactory onGetViewFactory(Intent intent) { - return new SingleCardWidgetFactory(this.getApplicationContext(), intent); - } -} diff --git a/app/src/main/res/layout/widget_single_card.xml b/app/src/main/res/layout/widget_single_card.xml index a0ccfafa7..780f97375 100644 --- a/app/src/main/res/layout/widget_single_card.xml +++ b/app/src/main/res/layout/widget_single_card.xml @@ -3,5 +3,6 @@ xmlns:tools="http://schemas.android.com/tools" android:id="@+id/title" android:layout_width="match_parent" + android:text="Test-Text Initial" android:layout_height="match_parent" tools:text="@tools:sample/lorem/random" /> diff --git a/app/src/main/res/xml/widget_single_card_info.xml b/app/src/main/res/xml/widget_single_card_info.xml new file mode 100644 index 000000000..2b8ab116e --- /dev/null +++ b/app/src/main/res/xml/widget_single_card_info.xml @@ -0,0 +1,10 @@ +<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" + android:minWidth="40dp" + android:minHeight="40dp" + android:updatePeriodMillis="86400000" + android:previewImage="@drawable/ic_app_logo" + android:initialLayout="@layout/widget_single_card" + android:resizeMode="horizontal|vertical" + android:configure="it.niedermann.nextcloud.deck.ui.widget.singlecard.SelectCardForWidgetActivity" + android:widgetCategory="home_screen"> +</appwidget-provider> |