diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0c6edab4..f0dd9cb4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -45,13 +45,22 @@ android:configChanges="orientation|screenSize" android:label="@string/send_message_title" android:theme="@style/WulkanowyTheme.NoActionBar" /> + + + + + diff --git a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt index b3b6f5e3..74f9fa65 100644 --- a/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt +++ b/app/src/main/java/io/github/wulkanowy/data/db/SharedPrefHelper.kt @@ -6,18 +6,16 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton +@SuppressLint("ApplySharedPref") class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) { - @SuppressLint("ApplySharedPref") fun putLong(key: String, value: Long, sync: Boolean = false) { sharedPref.edit().putLong(key, value).apply { if (sync) commit() else apply() } } - fun getLong(key: String, defaultValue: Long): Long { - return sharedPref.getLong(key, defaultValue) - } + fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue) fun delete(key: String) { sharedPref.edit().remove(key).apply() diff --git a/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt b/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt index 7f477630..2b48029e 100644 --- a/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt +++ b/app/src/main/java/io/github/wulkanowy/di/BuilderModule.kt @@ -9,7 +9,8 @@ import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainModule import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity import io.github.wulkanowy.ui.modules.splash.SplashActivity -import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetProvider +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureActivity +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider @Module internal abstract class BuilderModule { @@ -29,6 +30,9 @@ internal abstract class BuilderModule { @ContributesAndroidInjector abstract fun bindMessageSendActivity(): SendMessageActivity + @ContributesAndroidInjector + abstract fun bindTimetableWidgetAccountActivity(): TimetableWidgetConfigureActivity + @ContributesAndroidInjector abstract fun bindTimetableWidgetProvider(): TimetableWidgetProvider } diff --git a/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt b/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt index 0432ee14..f3429457 100644 --- a/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt +++ b/app/src/main/java/io/github/wulkanowy/services/widgets/TimetableWidgetService.kt @@ -7,7 +7,7 @@ import io.github.wulkanowy.data.db.SharedPrefHelper import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.timetable.TimetableRepository -import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetFactory +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetFactory import io.github.wulkanowy.utils.SchedulersProvider import javax.inject.Inject 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 new file mode 100644 index 00000000..37d0571a --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureActivity.kt @@ -0,0 +1,79 @@ +package io.github.wulkanowy.ui.modules.timetablewidget + +import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS +import android.content.Intent +import android.os.Bundle +import android.widget.Toast +import android.widget.Toast.LENGTH_LONG +import eu.davidea.flexibleadapter.FlexibleAdapter +import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager +import eu.davidea.flexibleadapter.items.AbstractFlexibleItem +import io.github.wulkanowy.R +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 javax.inject.Inject + +class TimetableWidgetConfigureActivity : BaseActivity(), TimetableWidgetConfigureView { + + @Inject + lateinit var configureAdapter: FlexibleAdapter> + + @Inject + lateinit var presenter: TimetableWidgetConfigurePresenter + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setResult(RESULT_CANCELED) + setContentView(R.layout.activity_timetable_widget_configure) + + intent.extras.let { + presenter.onAttachView(this, it?.getInt(EXTRA_APPWIDGET_ID), it?.getBoolean(EXTRA_FROM_PROVIDER)) + } + } + + override fun initView() { + timetableWidgetConfigureRecycler.apply { + adapter = configureAdapter + layoutManager = SmoothScrollLinearLayoutManager(context) + } + configureAdapter.setOnItemClickListener { presenter.onItemSelect(it) } + } + + override fun updateData(data: List) { + configureAdapter.updateDataSet(data) + } + + override fun updateTimetableWidget(widgetId: Int) { + sendBroadcast(Intent(this, TimetableWidgetProvider::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, 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/timetablewidget/TimetableWidgetConfigureItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureItem.kt new file mode 100644 index 00000000..f6ec1519 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureItem.kt @@ -0,0 +1,53 @@ +package io.github.wulkanowy.ui.modules.timetablewidget + +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 kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.item_account.* + +class TimetableWidgetConfigureItem(val student: Student, private 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/timetablewidget/TimetableWidgetConfigurePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigurePresenter.kt new file mode 100644 index 00000000..5a7bdd7c --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigurePresenter.kt @@ -0,0 +1,65 @@ +package io.github.wulkanowy.ui.modules.timetablewidget + +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.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey +import io.github.wulkanowy.utils.SchedulersProvider +import javax.inject.Inject + +class TimetableWidgetConfigurePresenter @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 + + private var isFromProvider = false + + fun onAttachView(view: TimetableWidgetConfigureView, appWidgetId: Int?, isFromProvider: Boolean?) { + super.onAttachView(view) + this.appWidgetId = appWidgetId + this.isFromProvider = isFromProvider ?: false + view.initView() + loadData() + } + + fun onItemSelect(item: AbstractFlexibleItem<*>) { + if (item is TimetableWidgetConfigureItem) { + registerStudent(item.student) + } + } + + private fun loadData() { + disposable.add(studentRepository.getSavedStudents(false) + .map { it to appWidgetId?.let { id -> sharedPref.getLong(getStudentWidgetKey(id), 0) } } + .map { (students, currentStudentId) -> + students.map { student -> TimetableWidgetConfigureItem(student, student.id == currentStudentId) } + } + .subscribeOn(schedulers.backgroundThread) + .observeOn(schedulers.mainThread) + .subscribe({ + when { + it.isEmpty() -> view?.openLoginView() + it.size == 1 && !isFromProvider -> registerStudent(it.single().student) + else -> view?.updateData(it) + } + }, { errorHandler.dispatch(it) })) + } + + private fun registerStudent(student: Student) { + appWidgetId?.also { + sharedPref.putLong(getStudentWidgetKey(it), student.id) + view?.apply { + updateTimetableWidget(it) + setSuccessResult(it) + } + } + view?.finishView() + } +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt new file mode 100644 index 00000000..98c800d4 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetConfigureView.kt @@ -0,0 +1,18 @@ +package io.github.wulkanowy.ui.modules.timetablewidget + +import io.github.wulkanowy.ui.base.BaseView + +interface TimetableWidgetConfigureView : BaseView { + + fun initView() + + fun updateData(data: List) + + fun updateTimetableWidget(widgetId: Int) + + fun setSuccessResult(widgetId: Int) + + fun finishView() + + fun openLoginView() +} diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt similarity index 67% rename from app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt index f2d40ba7..b288f7b7 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetFactory.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetFactory.kt @@ -1,5 +1,6 @@ -package io.github.wulkanowy.ui.widgets.timetable +package io.github.wulkanowy.ui.modules.timetablewidget +import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_ID import android.content.Context import android.content.Intent import android.graphics.Paint.ANTI_ALIAS_FLAG @@ -15,9 +16,11 @@ import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.timetable.TimetableRepository +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey +import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.toFormattedString -import io.reactivex.Single +import io.reactivex.Maybe import org.threeten.bp.LocalDate import timber.log.Timber @@ -48,28 +51,37 @@ class TimetableWidgetFactory( override fun onDestroy() {} override fun onDataSetChanged() { - intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) } - ?.let { date -> - try { - lessons = studentRepository.isStudentSaved() - .flatMap { isSaved -> - if (isSaved) { - studentRepository.getCurrentStudent() - .flatMap { semesterRepository.getCurrentSemester(it) } - .flatMap { timetableRepository.getTimetable(it, date, date) } - } else Single.just(emptyList()) - } - .map { item -> item.sortedBy { it.number } } - .subscribeOn(schedulers.backgroundThread) - .blockingGet() - } catch (e: Exception) { - Timber.e(e, "An error has occurred while downloading data for the widget") - } + intent?.extras?.getInt(EXTRA_APPWIDGET_ID)?.let { appWidgetId -> + val date = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(appWidgetId), 0)) + val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0) + + lessons = try { + studentRepository.isStudentSaved() + .filter { true } + .flatMap { studentRepository.getSavedStudents().toMaybe() } + .flatMap { + if (studentId == 0L) throw IllegalArgumentException("Student id is 0") + + it.singleOrNull { student -> student.id == studentId } + .let { student -> + if (student != null) Maybe.just(student) + else Maybe.empty() + } + } + .flatMap { semesterRepository.getCurrentSemester(it).toMaybe() } + .flatMap { timetableRepository.getTimetable(it, date, date).toMaybe() } + .map { item -> item.sortedBy { it.number } } + .subscribeOn(schedulers.backgroundThread) + .blockingGet(emptyList()) + } catch (e: Exception) { + Timber.e(e, "An error has occurred in timetable widget factory") + emptyList() } + } } override fun getViewAt(position: Int): RemoteViews? { - if (position == INVALID_POSITION || lessons.getOrNull(position) === null) return null + if (position == INVALID_POSITION || lessons.getOrNull(position) == null) return null return RemoteViews(context.packageName, R.layout.item_widget_timetable).apply { lessons[position].let { diff --git a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt similarity index 57% rename from app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt rename to app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt index 402366ec..83334c78 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/widgets/timetable/TimetableWidgetProvider.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetablewidget/TimetableWidgetProvider.kt @@ -1,4 +1,4 @@ -package io.github.wulkanowy.ui.widgets.timetable +package io.github.wulkanowy.ui.modules.timetablewidget import android.app.PendingIntent import android.app.PendingIntent.FLAG_UPDATE_CURRENT @@ -10,21 +10,28 @@ import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK +import android.content.Intent.FLAG_ACTIVITY_NEW_TASK 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.Student +import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.services.widgets.TimetableWidgetService 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.FirebaseAnalyticsHelper +import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.previousSchoolDay +import io.github.wulkanowy.utils.shortcutWeekDayName import io.github.wulkanowy.utils.toFormattedString -import io.github.wulkanowy.utils.weekDayName +import io.reactivex.Maybe import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate.now +import timber.log.Timber import javax.inject.Inject class TimetableWidgetProvider : BroadcastReceiver() { @@ -32,13 +39,21 @@ class TimetableWidgetProvider : BroadcastReceiver() { @Inject lateinit var appWidgetManager: AppWidgetManager + @Inject + lateinit var studentRepository: StudentRepository + @Inject lateinit var sharedPref: SharedPrefHelper + @Inject + lateinit var schedulers: SchedulersProvider + @Inject lateinit var analytics: FirebaseAnalyticsHelper companion object { + const val EXTRA_FROM_PROVIDER = "extraFromProvider" + const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget" const val EXTRA_BUTTON_TYPE = "extraButtonType" @@ -49,7 +64,9 @@ class TimetableWidgetProvider : BroadcastReceiver() { const val BUTTON_RESET = "buttonReset" - fun createWidgetKey(appWidgetId: Int) = "timetable_widget_$appWidgetId" + fun getDateWidgetKey(appWidgetId: Int) = "timetable_widget_date_$appWidgetId" + + fun getStudentWidgetKey(appWidgetId: Int) = "timetable_widget_student_$appWidgetId" } override fun onReceive(context: Context, intent: Intent) { @@ -63,12 +80,14 @@ class TimetableWidgetProvider : BroadcastReceiver() { private fun onUpdate(context: Context, intent: Intent) { if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) { intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId -> - updateWidget(context, appWidgetId, now().nextOrSameSchoolDay) + val student = getStudent(sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0), appWidgetId) + updateWidget(context, appWidgetId, now().nextOrSameSchoolDay, student) } } else { val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE) val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0) - val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(createWidgetKey(toggledWidgetId), 0)) + val student = getStudent(sharedPref.getLong(getStudentWidgetKey(toggledWidgetId), 0), toggledWidgetId) + val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(toggledWidgetId), 0)) val date = when (buttonType) { BUTTON_RESET -> now().nextOrSameSchoolDay BUTTON_NEXT -> savedDate.nextSchoolDay @@ -76,35 +95,46 @@ class TimetableWidgetProvider : BroadcastReceiver() { else -> now().nextOrSameSchoolDay } if (!buttonType.isNullOrBlank()) analytics.logEvent("changed_timetable_widget_day", "button" to buttonType) - updateWidget(context, toggledWidgetId, date) + updateWidget(context, toggledWidgetId, date, student) } } private fun onDelete(intent: Intent) { intent.getIntExtra(EXTRA_APPWIDGET_ID, 0).let { - if (it != 0) sharedPref.delete(createWidgetKey(it)) + if (it != 0) { + sharedPref.apply { + delete(getStudentWidgetKey(it)) + delete(getDateWidgetKey(it)) + } + } } } - private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate) { + private fun updateWidget(context: Context, appWidgetId: Int, date: LocalDate, student: Student?) { RemoteViews(context.packageName, R.layout.widget_timetable).apply { setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty) - setTextViewText(R.id.timetableWidgetDay, date.weekDayName.capitalize()) - setTextViewText(R.id.timetableWidgetDate, date.toFormattedString()) + setTextViewText(R.id.timetableWidgetDate, "${date.shortcutWeekDayName.capitalize()} ${date.toFormattedString()}") + setTextViewText(R.id.timetableWidgetName, student?.studentName ?: context.getString(R.string.all_no_data)) setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java) - .apply { action = createWidgetKey(appWidgetId) }) + .apply { putExtra(EXTRA_APPWIDGET_ID, appWidgetId) }) setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT)) setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV)) - createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET).also { + createNavIntent(context, Int.MAX_VALUE - appWidgetId, appWidgetId, BUTTON_RESET).let { setOnClickPendingIntent(R.id.timetableWidgetDate, it) - setOnClickPendingIntent(R.id.timetableWidgetDay, it) + setOnClickPendingIntent(R.id.timetableWidgetName, it) } + setOnClickPendingIntent(R.id.timetableWidgetAccount, PendingIntent.getActivity(context, -Int.MAX_VALUE + appWidgetId, + Intent(context, TimetableWidgetConfigureActivity::class.java).apply { + addFlags(FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_CLEAR_TASK) + putExtra(EXTRA_APPWIDGET_ID, appWidgetId) + putExtra(EXTRA_FROM_PROVIDER, true) + }, FLAG_UPDATE_CURRENT)) setPendingIntentTemplate(R.id.timetableWidgetList, PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply { putExtra(EXTRA_START_MENU_INDEX, 3) }, FLAG_UPDATE_CURRENT)) }.also { - sharedPref.putLong(createWidgetKey(appWidgetId), date.toEpochDay(), true) + sharedPref.putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true) appWidgetManager.apply { notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList) updateAppWidget(appWidgetId, it) @@ -120,4 +150,29 @@ class TimetableWidgetProvider : BroadcastReceiver() { putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId) }, FLAG_UPDATE_CURRENT) } + + private fun getStudent(id: Long, appWidgetId: Int): Student? { + return try { + studentRepository.isStudentSaved() + .filter { true } + .flatMap { studentRepository.getSavedStudents(false).toMaybe() } + .flatMap { students -> + students.singleOrNull { student -> student.id == id } + .let { student -> + if (student != null) { + Maybe.just(student) + } else { + studentRepository.getCurrentStudent(false) + .toMaybe() + .doOnSuccess { sharedPref.putLong(getStudentWidgetKey(appWidgetId), it.id) } + } + } + } + .subscribeOn(schedulers.backgroundThread) + .blockingGet() + } catch (e: Exception) { + Timber.e(e, "An error has occurred in timetable widget provider") + null + } + } } diff --git a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt index 886b3d4d..426816f4 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/TimeExtension.kt @@ -99,6 +99,9 @@ inline val LocalDate.previousOrSameSchoolDay: LocalDate inline val LocalDate.weekDayName: String get() = this.format(ofPattern("EEEE", Locale.getDefault())) +inline val LocalDate.shortcutWeekDayName: String + get() = this.format(ofPattern("EEE", Locale.getDefault())) + inline val LocalDate.monday: LocalDate get() = this.with(MONDAY) diff --git a/app/src/main/res/drawable-hdpi/ic_widget_account.png b/app/src/main/res/drawable-hdpi/ic_widget_account.png new file mode 100644 index 00000000..4cb5ac89 Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_widget_account.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_widget_account.png b/app/src/main/res/drawable-mdpi/ic_widget_account.png new file mode 100644 index 00000000..237a6b6c Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_widget_account.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_widget_account.png b/app/src/main/res/drawable-xhdpi/ic_widget_account.png new file mode 100644 index 00000000..0ea798a8 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_widget_account.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_widget_account.png b/app/src/main/res/drawable-xxhdpi/ic_widget_account.png new file mode 100644 index 00000000..0f8933b1 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_widget_account.png differ diff --git a/app/src/main/res/drawable/img_timetable_widget_preview.png b/app/src/main/res/drawable/img_timetable_widget_preview.png index 60a35ab6..55026025 100644 Binary files a/app/src/main/res/drawable/img_timetable_widget_preview.png and b/app/src/main/res/drawable/img_timetable_widget_preview.png differ diff --git a/app/src/main/res/layout/activity_timetable_widget_configure.xml b/app/src/main/res/layout/activity_timetable_widget_configure.xml new file mode 100644 index 00000000..2a95e01d --- /dev/null +++ b/app/src/main/res/layout/activity_timetable_widget_configure.xml @@ -0,0 +1,31 @@ + + + + + + + diff --git a/app/src/main/res/layout/item_account.xml b/app/src/main/res/layout/item_account.xml index 56f553e5..5f76dded 100644 --- a/app/src/main/res/layout/item_account.xml +++ b/app/src/main/res/layout/item_account.xml @@ -33,7 +33,8 @@ android:ellipsize="end" android:maxLines="1" android:textSize="16sp" - tools:text="@tools:sample/lorem/random" /> + tools:text="@tools:sample/lorem/random" + android:textColor="?android:textColorSecondary"/> diff --git a/app/src/main/res/layout/item_widget_timetable.xml b/app/src/main/res/layout/item_widget_timetable.xml index af055280..aa808864 100644 --- a/app/src/main/res/layout/item_widget_timetable.xml +++ b/app/src/main/res/layout/item_widget_timetable.xml @@ -7,7 +7,7 @@ android:background="@drawable/ic_all_divider" android:minHeight="45dp" android:orientation="horizontal" - tools:context=".ui.widgets.timetable.TimetableWidgetFactory"> + tools:context=".ui.modules.timetablewidget.TimetableWidgetFactory"> + tools:context=".ui.modules.timetablewidget.TimetableWidgetProvider"> + + + + + + + + + - - - - - @color/about_libraries_dividerDark_openSource_dark @color/about_libraries_dividerLight_openSource_dark - - diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 3caa356e..144772a5 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -233,8 +233,6 @@ Brak lekcji - Dziś - Jutro diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e0708095..a4bf80ed 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,7 +2,4 @@ 8dp 8dp - - - 60dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6a56b441..a00514be 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -218,8 +218,6 @@ No lessons - Today - Tomorrow diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 4bbe3bc1..58cd99eb 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -40,4 +40,12 @@ + + diff --git a/app/src/main/res/xml/provider_widget_timetable.xml b/app/src/main/res/xml/provider_widget_timetable.xml index 48c6ba39..1e0eedcb 100644 --- a/app/src/main/res/xml/provider_widget_timetable.xml +++ b/app/src/main/res/xml/provider_widget_timetable.xml @@ -1,8 +1,11 @@