From f84040109c2a2df0dedf678c793955bafb40c0ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Mon, 29 Apr 2019 14:33:33 +0200 Subject: [PATCH] Add lucky number widget (#292) --- .circleci/config.yml | 4 +- app/src/main/AndroidManifest.xml | 22 ++- .../io/github/wulkanowy/di/BuilderModule.kt | 8 + .../LuckyNumberWidgetConfigureActivity.kt | 77 ++++++++ .../LuckyNumberWidgetConfigureItem.kt | 54 ++++++ .../LuckyNumberWidgetConfigurePresenter.kt | 62 ++++++ .../LuckyNumberWidgetConfigureView.kt | 19 ++ .../LuckyNumberWidgetProvider.kt | 180 ++++++++++++++++++ .../TimetableWidgetConfigureActivity.kt | 6 +- .../drawable/background_rounded_corner.xml | 6 + .../res/drawable/ic_widget_clover_24dp.png | Bin 0 -> 1060 bytes .../img_luckynumber_widget_preview.png | Bin 0 -> 19550 bytes ...gure.xml => activity_widget_configure.xml} | 6 +- .../main/res/layout/widget_luckynumber.xml | 63 ++++++ app/src/main/res/values/api_endpoints.xml | 2 +- app/src/main/res/values/styles.xml | 2 +- .../res/xml/provider_widget_lucky_number.xml | 14 ++ .../res/xml/provider_widget_timetable.xml | 4 +- 18 files changed, 517 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureActivity.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureItem.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt create mode 100644 app/src/main/res/drawable/background_rounded_corner.xml create mode 100644 app/src/main/res/drawable/ic_widget_clover_24dp.png create mode 100644 app/src/main/res/drawable/img_luckynumber_widget_preview.png rename app/src/main/res/layout/{activity_timetable_widget_configure.xml => activity_widget_configure.xml} (85%) create mode 100644 app/src/main/res/layout/widget_luckynumber.xml create mode 100644 app/src/main/res/xml/provider_widget_lucky_number.xml diff --git a/.circleci/config.yml b/.circleci/config.yml index d4e59be19..f6646b523 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,11 +7,11 @@ references: container_config: &container_config docker: - - image: circleci/android:api-28-alpha + - image: circleci/android:api-28 working_directory: *workspace_root environment: environment: - JVM_OPTS: -Xmx3200m + _JAVA_OPTS: -Xmx2048m attach_workspace: &attach_workspace attach_workspace: diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5b2819263..d670ef444 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -50,7 +50,16 @@ android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity" android:noHistory="true" android:excludeFromRecents="true" - android:theme="@style/WulkanowyTheme.TimetableWidgetAccount"> + android:theme="@style/WulkanowyTheme.WidgetAccountSwitcher"> + + + + + @@ -72,6 +81,17 @@ android:resource="@xml/provider_widget_timetable" /> + + + + + + + > + + @Inject + lateinit var presenter: LuckyNumberWidgetConfigurePresenter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setResult(RESULT_CANCELED) + setContentView(R.layout.activity_widget_configure) + + intent.extras.let { + presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID)) + } + } + + override fun initView() { + widgetConfigureRecycler.apply { + adapter = configureAdapter + layoutManager = SmoothScrollLinearLayoutManager(context) + } + configureAdapter.setOnItemClickListener { presenter.onItemSelect(it) } + } + + override fun updateData(data: List) { + configureAdapter.updateDataSet(data) + } + + override fun updateLuckyNumberWidget(widgetId: Int) { + sendBroadcast(Intent(this, LuckyNumberWidgetProvider::class.java) + .apply { + action = ACTION_APPWIDGET_UPDATE + putExtra(EXTRA_APPWIDGET_IDS, intArrayOf(widgetId)) + }) + } + + override fun setSuccessResult(widgetId: Int) { + setResult(RESULT_OK, Intent().apply { putExtra(EXTRA_APPWIDGET_ID, widgetId) }) + } + + override fun showError(text: String, error: Throwable) { + Toast.makeText(this, text, Toast.LENGTH_LONG).show() + } + + override fun finishView() { + finish() + } + + override fun openLoginView() { + startActivity(LoginActivity.getStartIntent(this)) + } + + override fun onDestroy() { + super.onDestroy() + presenter.onDetachView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureItem.kt new file mode 100644 index 000000000..bba0974b6 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureItem.kt @@ -0,0 +1,54 @@ +package io.github.wulkanowy.ui.modules.luckynumberwidget + +import android.annotation.SuppressLint +import android.view.View +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import eu.davidea.flexibleadapter.items.IFlexible +import eu.davidea.viewholders.FlexibleViewHolder +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureItem +import kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.item_account.* + +class LuckyNumberWidgetConfigureItem(var student: Student, val isCurrent: Boolean) : + AbstractFlexibleItem() { + + override fun getLayoutRes() = R.layout.item_account + + override fun createViewHolder(view: View, adapter: FlexibleAdapter>): ViewHolder { + return ViewHolder(view, adapter) + } + + @SuppressLint("SetTextI18n") + override fun bindViewHolder(adapter: FlexibleAdapter>, holder: ViewHolder, position: Int, payloads: MutableList) { + holder.apply { + accountItemName.text = "${student.studentName} ${student.className}" + accountItemSchool.text = student.schoolName + accountItemImage.setBackgroundResource(if (isCurrent) R.drawable.ic_account_circular_border else 0) + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as TimetableWidgetConfigureItem + + if (student != other.student) return false + + return true + } + + override fun hashCode(): Int { + var result = student.hashCode() + result = 31 * result + student.id.toInt() + return result + } + + class ViewHolder(view: View, adapter: FlexibleAdapter<*>) : FlexibleViewHolder(view, adapter), LayoutContainer { + override val containerView: View + get() = contentView + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt new file mode 100644 index 000000000..3f808f09a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigurePresenter.kt @@ -0,0 +1,62 @@ +package io.github.wulkanowy.ui.modules.luckynumberwidget + +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.data.db.SharedPrefHelper +import io.github.wulkanowy.data.db.entities.Student +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.base.BasePresenter +import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.createWidgetKey +import io.github.wulkanowy.utils.SchedulersProvider +import javax.inject.Inject + +class LuckyNumberWidgetConfigurePresenter @Inject constructor( + private val errorHandler: ErrorHandler, + private val schedulers: SchedulersProvider, + private val studentRepository: StudentRepository, + private val sharedPref: SharedPrefHelper +) : BasePresenter(errorHandler) { + + private var appWidgetId: Int? = null + + fun onAttachView(view: LuckyNumberWidgetConfigureView, appWidgetId: Int?) { + super.onAttachView(view) + this.appWidgetId = appWidgetId + view.initView() + loadData() + } + + fun onItemSelect(item: AbstractFlexibleItem<*>) { + if (item is LuckyNumberWidgetConfigureItem) { + registerStudent(item.student) + } + } + + private fun loadData() { + disposable.add(studentRepository.getSavedStudents(false) + .map { it to appWidgetId?.let { id -> sharedPref.getLong(createWidgetKey(id), 0) } } + .map { (students, currentStudentId) -> + students.map { student -> LuckyNumberWidgetConfigureItem(student, student.id == currentStudentId) } + } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .subscribe({ + when { + it.isEmpty() -> view?.openLoginView() + it.size == 1 -> registerStudent(it.single().student) + else -> view?.updateData(it) + } + }, { errorHandler.dispatch(it) })) + } + + private fun registerStudent(student: Student) { + appWidgetId?.also { + sharedPref.putLong(createWidgetKey(it), student.id) + view?.apply { + updateLuckyNumberWidget(it) + setSuccessResult(it) + } + } + view?.finishView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt new file mode 100644 index 000000000..49c3f1dcd --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetConfigureView.kt @@ -0,0 +1,19 @@ +package io.github.wulkanowy.ui.modules.luckynumberwidget + +import io.github.wulkanowy.ui.base.BaseView +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureItem + +interface LuckyNumberWidgetConfigureView : BaseView { + + fun initView() + + fun updateData(data: List) + + fun updateLuckyNumberWidget(widgetId: Int) + + fun setSuccessResult(widgetId: Int) + + fun finishView() + + fun openLoginView() +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt new file mode 100644 index 000000000..40352279d --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/luckynumberwidget/LuckyNumberWidgetProvider.kt @@ -0,0 +1,180 @@ +package io.github.wulkanowy.ui.modules.luckynumberwidget + +import android.annotation.TargetApi +import android.app.PendingIntent +import android.appwidget.AppWidgetManager +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_DELETED +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_OPTIONS +import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT +import android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.os.Build +import android.view.View.GONE +import android.view.View.VISIBLE +import android.widget.RemoteViews +import dagger.android.AndroidInjection +import io.github.wulkanowy.R +import io.github.wulkanowy.data.db.SharedPrefHelper +import io.github.wulkanowy.data.db.entities.LuckyNumber +import io.github.wulkanowy.data.repositories.luckynumber.LuckyNumberRepository +import io.github.wulkanowy.data.repositories.semester.SemesterRepository +import io.github.wulkanowy.data.repositories.student.StudentRepository +import io.github.wulkanowy.ui.modules.main.MainActivity +import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX +import io.github.wulkanowy.utils.SchedulersProvider +import io.reactivex.Maybe +import timber.log.Timber +import javax.inject.Inject + +class LuckyNumberWidgetProvider : BroadcastReceiver() { + + @Inject + lateinit var studentRepository: StudentRepository + + @Inject + lateinit var semesterRepository: SemesterRepository + + @Inject + lateinit var luckyNumberRepository: LuckyNumberRepository + + @Inject + lateinit var schedulers: SchedulersProvider + + @Inject + lateinit var appWidgetManager: AppWidgetManager + + @Inject + lateinit var sharedPref: SharedPrefHelper + + companion object { + fun createWidgetKey(appWidgetId: Int) = "lucky_number_widget_$appWidgetId" + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + override fun onReceive(context: Context, intent: Intent) { + AndroidInjection.inject(this, context) + when (intent.action) { + ACTION_APPWIDGET_UPDATE -> onUpdate(context, intent) + ACTION_APPWIDGET_DELETED -> onDelete(intent) + ACTION_APPWIDGET_OPTIONS_CHANGED -> onOptionsChange(context, intent) + } + } + + private fun onUpdate(context: Context, intent: Intent) { + intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS).forEach { appWidgetId -> + RemoteViews(context.packageName, R.layout.widget_luckynumber).apply { + setTextViewText(R.id.luckyNumberWidgetNumber, + getLuckyNumber(sharedPref.getLong(createWidgetKey(appWidgetId), 0), appWidgetId)?.luckyNumber?.toString() ?: "#" + ) + setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, + PendingIntent.getActivity(context, 2, MainActivity.getStartIntent(context).apply { + putExtra(EXTRA_START_MENU_INDEX, 4) + }, PendingIntent.FLAG_UPDATE_CURRENT)) + }.also { + setStyles(it, intent) + appWidgetManager.updateAppWidget(appWidgetId, it) + } + } + } + + private fun onDelete(intent: Intent) { + intent.getIntExtra(EXTRA_APPWIDGET_ID, 0).let { + if (it != 0) sharedPref.delete(createWidgetKey(it)) + } + } + + private fun getLuckyNumber(studentId: Long, appWidgetId: Int): LuckyNumber? { + return try { + studentRepository.isStudentSaved() + .filter { true } + .flatMap { studentRepository.getSavedStudents().toMaybe() } + .flatMap { students -> + students.singleOrNull { student -> student.id == studentId } + .let { student -> + if (student != null) { + Maybe.just(student) + } else { + studentRepository.getCurrentStudent(false) + .toMaybe() + .doOnSuccess { sharedPref.putLong(createWidgetKey(appWidgetId), it.id) } + } + } + } + .flatMap { semesterRepository.getCurrentSemester(it).toMaybe() } + .flatMap { luckyNumberRepository.getLuckyNumber(it) } + .subscribeOn(schedulers.backgroundThread) + .blockingGet() + } catch (e: Exception) { + Timber.e(e, "An error has occurred in lucky number provider") + null + } + } + + private fun onOptionsChange(context: Context, intent: Intent) { + intent.extras?.let { extras -> + RemoteViews(context.packageName, R.layout.widget_luckynumber).apply { + setStyles(this, intent) + appWidgetManager.updateAppWidget(extras.getInt(EXTRA_APPWIDGET_ID), this) + } + } + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private fun setStyles(views: RemoteViews, intent: Intent) { + val options = intent.extras?.getBundle(EXTRA_APPWIDGET_OPTIONS) + + val maxWidth = options?.getInt(OPTION_APPWIDGET_MAX_WIDTH) ?: 150 + val maxHeight = options?.getInt(OPTION_APPWIDGET_MAX_HEIGHT) ?: 40 + + Timber.d("New luckynumber widget measurement: %dx%d", maxWidth, maxHeight) + + when { + // 1x1 + maxWidth < 150 && maxHeight < 110 -> { + Timber.d("Luckynumber widget size: 1x1") + views.run { + setViewVisibility(R.id.luckyNumberWidgetImageTop, GONE) + setViewVisibility(R.id.luckyNumberWidgetImageLeft, GONE) + setViewVisibility(R.id.luckyNumberWidgetTitle, GONE) + setViewVisibility(R.id.luckyNumberWidgetNumber, VISIBLE) + } + } + // 1x2 + maxWidth < 150 && maxHeight > 110 -> { + Timber.d("Luckynumber widget size: 1x2") + views.run { + setViewVisibility(R.id.luckyNumberWidgetImageTop, VISIBLE) + setViewVisibility(R.id.luckyNumberWidgetImageLeft, GONE) + setViewVisibility(R.id.luckyNumberWidgetTitle, GONE) + setViewVisibility(R.id.luckyNumberWidgetNumber, VISIBLE) + } + } + // 2x1 + maxWidth >= 150 && maxHeight <= 110 -> { + Timber.d("Luckynumber widget size: 2x1") + views.run { + setViewVisibility(R.id.luckyNumberWidgetImageTop, GONE) + setViewVisibility(R.id.luckyNumberWidgetImageLeft, VISIBLE) + setViewVisibility(R.id.luckyNumberWidgetTitle, GONE) + setViewVisibility(R.id.luckyNumberWidgetNumber, VISIBLE) + } + } + // 2x2 and bigger + else -> { + Timber.d("Luckynumber widget size: 2x2 and bigger") + views.run { + setViewVisibility(R.id.luckyNumberWidgetImageTop, GONE) + setViewVisibility(R.id.luckyNumberWidgetImageLeft, GONE) + setViewVisibility(R.id.luckyNumberWidgetTitle, VISIBLE) + setViewVisibility(R.id.luckyNumberWidgetNumber, VISIBLE) + } + } + } + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt index 37d0571a4..468567f18 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt @@ -15,7 +15,7 @@ import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.EXTRA_FROM_PROVIDER import io.github.wulkanowy.utils.setOnItemClickListener -import kotlinx.android.synthetic.main.activity_timetable_widget_configure.* +import kotlinx.android.synthetic.main.activity_widget_configure.* import javax.inject.Inject class TimetableWidgetConfigureActivity : BaseActivity(), TimetableWidgetConfigureView { @@ -29,7 +29,7 @@ class TimetableWidgetConfigureActivity : BaseActivity(), TimetableWidgetConfigur override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setResult(RESULT_CANCELED) - setContentView(R.layout.activity_timetable_widget_configure) + setContentView(R.layout.activity_widget_configure) intent.extras.let { presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID), it?.getBoolean(EXTRA_FROM_PROVIDER)) @@ -37,7 +37,7 @@ class TimetableWidgetConfigureActivity : BaseActivity(), TimetableWidgetConfigur } override fun initView() { - timetableWidgetConfigureRecycler.apply { + widgetConfigureRecycler.apply { adapter = configureAdapter layoutManager = SmoothScrollLinearLayoutManager(context) } diff --git a/app/src/main/res/drawable/background_rounded_corner.xml b/app/src/main/res/drawable/background_rounded_corner.xml new file mode 100644 index 000000000..116973b54 --- /dev/null +++ b/app/src/main/res/drawable/background_rounded_corner.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_widget_clover_24dp.png b/app/src/main/res/drawable/ic_widget_clover_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..b1a7832a2f288201c2cf4ba91f2bfb8baa17893e GIT binary patch literal 1060 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 + + + + + + + + + + diff --git a/app/src/main/res/values/api_endpoints.xml b/app/src/main/res/values/api_endpoints.xml index ff8cd23ca..e07f2b4b5 100644 --- a/app/src/main/res/values/api_endpoints.xml +++ b/app/src/main/res/values/api_endpoints.xml @@ -14,6 +14,6 @@ https://edu.gdansk.pl https://umt.tarnow.pl https://resman.pl - https://fakelog.cf + http://fakelog.cf diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 685bda9f1..58699c9e3 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -41,7 +41,7 @@ @android:color/white -