diff options
Diffstat (limited to 'app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote')
5 files changed, 352 insertions, 0 deletions
diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java new file mode 100644 index 00000000..777cd25e --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java @@ -0,0 +1,96 @@ +package it.niedermann.owncloud.notes.widget.singlenote; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; +import android.widget.RemoteViews; + +import java.util.NoSuchElementException; + +import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.preferences.DarkModeSetting; +import it.niedermann.owncloud.notes.edit.EditNoteActivity; +import it.niedermann.owncloud.notes.edit.BaseNoteFragment; +import it.niedermann.owncloud.notes.persistence.NotesDatabase; +import it.niedermann.owncloud.notes.NotesApplication; + +public class SingleNoteWidget extends AppWidgetProvider { + + private static final String TAG = SingleNoteWidget.class.getSimpleName(); + + static void updateAppWidget(Context context, AppWidgetManager awm, int[] appWidgetIds) { + final Intent templateIntent = new Intent(context, EditNoteActivity.class); + final NotesDatabase db = NotesDatabase.getInstance(context); + + for (int appWidgetId : appWidgetIds) { + try { + final SingleNoteWidgetData data = db.getSingleNoteWidgetData(appWidgetId); + + templateIntent.putExtra(BaseNoteFragment.PARAM_ACCOUNT_ID, data.getAccountId()); + + final PendingIntent templatePendingIntent = PendingIntent.getActivity(context, appWidgetId, templateIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + + Intent serviceIntent = new Intent(context, SingleNoteWidgetService.class); + serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); + + RemoteViews views; + + if (NotesApplication.isDarkThemeActive(context, DarkModeSetting.fromModeID(data.getThemeMode()))) { + views = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_dark); + views.setPendingIntentTemplate(R.id.single_note_widget_lv_dark, templatePendingIntent); + views.setRemoteAdapter(R.id.single_note_widget_lv_dark, serviceIntent); + views.setEmptyView(R.id.single_note_widget_lv_dark, R.id.widget_single_note_placeholder_tv_dark); + awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.single_note_widget_lv_dark); + } else { + 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); + } + awm.updateAppWidget(appWidgetId, views); + } catch (NoSuchElementException e) { + Log.i(TAG, "onUpdate has been triggered before the user finished configuring the widget"); + } + } + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + super.onUpdate(context, appWidgetManager, appWidgetIds); + updateAppWidget(context, appWidgetManager, appWidgetIds); + } + + @Override + public void onReceive(Context context, Intent intent) { + super.onReceive(context, intent); + AppWidgetManager awm = AppWidgetManager.getInstance(context); + + updateAppWidget(context, AppWidgetManager.getInstance(context), + (awm.getAppWidgetIds(new ComponentName(context, SingleNoteWidget.class)))); + } + + @Override + public void onDeleted(Context context, int[] appWidgetIds) { + final NotesDatabase db = NotesDatabase.getInstance(context); + + for (int appWidgetId : appWidgetIds) { + db.removeSingleNoteWidget(appWidgetId); + } + super.onDeleted(context, appWidgetIds); + } + + /** + * Update single note widget, if the note data was changed. + */ + public static void updateSingleNoteWidgets(Context context) { + context.sendBroadcast(new Intent(context, SingleNoteWidget.class).setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE)); + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetConfigurationActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetConfigurationActivity.java new file mode 100644 index 00000000..ef3bbbe6 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetConfigurationActivity.java @@ -0,0 +1,74 @@ +package it.niedermann.owncloud.notes.widget.singlenote; + +import android.app.Activity; +import android.appwidget.AppWidgetManager; +import android.content.Intent; +import android.database.SQLException; +import android.os.Bundle; +import android.view.Menu; +import android.view.View; +import android.widget.Toast; + +import androidx.appcompat.widget.Toolbar; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.exception.ExceptionHandler; +import it.niedermann.owncloud.notes.main.MainActivity; +import it.niedermann.owncloud.notes.shared.model.DBNote; +import it.niedermann.owncloud.notes.NotesApplication; + +public class SingleNoteWidgetConfigurationActivity extends MainActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Thread.currentThread().setUncaughtExceptionHandler(new ExceptionHandler(this)); + setResult(Activity.RESULT_CANCELED); + + fabCreate.setVisibility(View.GONE); + Toolbar toolbar = binding.activityNotesListView.toolbar; + SwipeRefreshLayout swipeRefreshLayout = binding.activityNotesListView.swiperefreshlayout; + toolbar.setTitle(R.string.activity_select_single_note); + swipeRefreshLayout.setEnabled(false); + swipeRefreshLayout.setRefreshing(false); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public void onNoteClick(int position, View v) { + final DBNote note = (DBNote) adapter.getItem(position); + final Bundle extras = getIntent().getExtras(); + + if (extras == null) { + finish(); + return; + } + + int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + + try { + db.createOrUpdateSingleNoteWidgetData( + new SingleNoteWidgetData( + appWidgetId, + note.getAccountId(), + note.getId(), + NotesApplication.getAppTheme(this).getModeId() + ) + ); + final Intent updateIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE, null, + getApplicationContext(), SingleNoteWidget.class) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + setResult(RESULT_OK, updateIntent); + getApplicationContext().sendBroadcast(updateIntent); + } catch (SQLException e) { + Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); + } + + finish(); + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetData.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetData.java new file mode 100644 index 00000000..79b83006 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetData.java @@ -0,0 +1,25 @@ +package it.niedermann.owncloud.notes.widget.singlenote; + +import it.niedermann.owncloud.notes.widget.AbstractWidgetData; + +public class SingleNoteWidgetData extends AbstractWidgetData { + private long noteId; + + public SingleNoteWidgetData() { + + } + + public SingleNoteWidgetData(int appWidgetId, long accountId, long noteId, int themeMode) { + super(appWidgetId, accountId, themeMode); + this.noteId = noteId; + } + + public long getNoteId() { + return noteId; + } + + public void setNoteId(long noteId) { + this.noteId = noteId; + } + +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java new file mode 100644 index 00000000..939c41ef --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetFactory.java @@ -0,0 +1,146 @@ +package it.niedermann.owncloud.notes.widget.singlenote; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import com.yydcdut.markdown.MarkdownProcessor; +import com.yydcdut.markdown.syntax.text.TextFactory; + +import java.util.NoSuchElementException; + +import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.preferences.DarkModeSetting; +import it.niedermann.owncloud.notes.edit.EditNoteActivity; +import it.niedermann.owncloud.notes.shared.model.DBNote; +import it.niedermann.owncloud.notes.persistence.NotesDatabase; +import it.niedermann.owncloud.notes.shared.util.MarkDownUtil; +import it.niedermann.owncloud.notes.NotesApplication; + +import static it.niedermann.owncloud.notes.shared.util.MarkDownUtil.parseCompat; + +public class SingleNoteWidgetFactory implements RemoteViewsService.RemoteViewsFactory { + + private final MarkdownProcessor markdownProcessor; + private final Context context; + private final int appWidgetId; + + private NotesDatabase db; + private DBNote note; + private boolean darkModeActive = false; + + private static final String TAG = SingleNoteWidget.class.getSimpleName(); + + SingleNoteWidgetFactory(Context context, Intent intent) { + this.context = context; + appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + db = NotesDatabase.getInstance(context); + markdownProcessor = new MarkdownProcessor(this.context); + markdownProcessor.factory(TextFactory.create()); + try { + SingleNoteWidgetData data = db.getSingleNoteWidgetData(appWidgetId); + darkModeActive = NotesApplication.isDarkThemeActive(context, DarkModeSetting.fromModeID(data.getThemeMode())); + } catch (NoSuchElementException e) { + Log.w(TAG, "Widget with ID " + appWidgetId + " seems to be not configured yet."); + } finally { + markdownProcessor.config(MarkDownUtil.getMarkDownConfiguration(this.context, darkModeActive).build()); + } + } + + @Override + public void onCreate() { + + } + + @Override + public void onDataSetChanged() { + try { + final SingleNoteWidgetData data = db.getSingleNoteWidgetData(appWidgetId); + final long noteId = data.getNoteId(); + Log.v(TAG, "Fetch note with id " + noteId); + note = db.getNote(data.getAccountId(), noteId); + + if (note == null) { + Log.e(TAG, "Error: note not found"); + } + } catch (NoSuchElementException e) { + Log.w(TAG, "Widget with ID " + appWidgetId + " seems to be not configured yet."); + } + } + + @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 (note != 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 (note == null) { + return null; + } + + RemoteViews note_content; + + final Intent fillInIntent = new Intent(); + final Bundle extras = new Bundle(); + + extras.putLong(EditNoteActivity.PARAM_NOTE_ID, note.getId()); + extras.putLong(EditNoteActivity.PARAM_ACCOUNT_ID, note.getAccountId()); + fillInIntent.putExtras(extras); + if (darkModeActive) { + note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content_dark); + note_content.setOnClickFillInIntent(R.id.single_note_content_tv_dark, fillInIntent); + note_content.setTextViewText(R.id.single_note_content_tv_dark, parseCompat(markdownProcessor, note.getContent())); + + } else { + note_content = new RemoteViews(context.getPackageName(), R.layout.widget_single_note_content); + note_content.setOnClickFillInIntent(R.id.single_note_content_tv, fillInIntent); + note_content.setTextViewText(R.id.single_note_content_tv, parseCompat(markdownProcessor, note.getContent())); + } + + return note_content; + } + + + // 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/owncloud/notes/widget/singlenote/SingleNoteWidgetService.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetService.java new file mode 100644 index 00000000..691acae9 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidgetService.java @@ -0,0 +1,11 @@ +package it.niedermann.owncloud.notes.widget.singlenote; + +import android.content.Intent; +import android.widget.RemoteViewsService; + +public class SingleNoteWidgetService extends RemoteViewsService { + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return new SingleNoteWidgetFactory(this.getApplicationContext(), intent); + } +} |