forked from github/wulkanowy-mirror
parent
aa6dcaff94
commit
c18877466f
@ -45,13 +45,22 @@
|
|||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:label="@string/send_message_title"
|
android:label="@string/send_message_title"
|
||||||
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
|
||||||
|
android:noHistory="true"
|
||||||
|
android:excludeFromRecents="true"
|
||||||
|
android:theme="@style/WulkanowyTheme.TimetableWidgetAccount">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".services.widgets.TimetableWidgetService"
|
android:name=".services.widgets.TimetableWidgetService"
|
||||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
android:name=".ui.widgets.timetable.TimetableWidgetProvider"
|
android:name=".ui.modules.timetablewidget.TimetableWidgetProvider"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/timetable_title">
|
android:label="@string/timetable_title">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -6,18 +6,16 @@ import javax.inject.Inject
|
|||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@SuppressLint("ApplySharedPref")
|
||||||
class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) {
|
class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) {
|
||||||
|
|
||||||
@SuppressLint("ApplySharedPref")
|
|
||||||
fun putLong(key: String, value: Long, sync: Boolean = false) {
|
fun putLong(key: String, value: Long, sync: Boolean = false) {
|
||||||
sharedPref.edit().putLong(key, value).apply {
|
sharedPref.edit().putLong(key, value).apply {
|
||||||
if (sync) commit() else apply()
|
if (sync) commit() else apply()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLong(key: String, defaultValue: Long): Long {
|
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)
|
||||||
return sharedPref.getLong(key, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun delete(key: String) {
|
fun delete(key: String) {
|
||||||
sharedPref.edit().remove(key).apply()
|
sharedPref.edit().remove(key).apply()
|
||||||
|
@ -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.main.MainModule
|
||||||
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
|
||||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
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
|
@Module
|
||||||
internal abstract class BuilderModule {
|
internal abstract class BuilderModule {
|
||||||
@ -29,6 +30,9 @@ internal abstract class BuilderModule {
|
|||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindMessageSendActivity(): SendMessageActivity
|
abstract fun bindMessageSendActivity(): SendMessageActivity
|
||||||
|
|
||||||
|
@ContributesAndroidInjector
|
||||||
|
abstract fun bindTimetableWidgetAccountActivity(): TimetableWidgetConfigureActivity
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindTimetableWidgetProvider(): TimetableWidgetProvider
|
abstract fun bindTimetableWidgetProvider(): TimetableWidgetProvider
|
||||||
}
|
}
|
||||||
|
@ -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.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
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 io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -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<AbstractFlexibleItem<*>>
|
||||||
|
|
||||||
|
@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<TimetableWidgetConfigureItem>) {
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
@ -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<TimetableWidgetConfigureItem.ViewHolder>() {
|
||||||
|
|
||||||
|
override fun getLayoutRes() = R.layout.item_account
|
||||||
|
|
||||||
|
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>): ViewHolder {
|
||||||
|
return ViewHolder(view, adapter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
@ -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<TimetableWidgetConfigureView>(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()
|
||||||
|
}
|
||||||
|
}
|
@ -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<TimetableWidgetConfigureItem>)
|
||||||
|
|
||||||
|
fun updateTimetableWidget(widgetId: Int)
|
||||||
|
|
||||||
|
fun setSuccessResult(widgetId: Int)
|
||||||
|
|
||||||
|
fun finishView()
|
||||||
|
|
||||||
|
fun openLoginView()
|
||||||
|
}
|
@ -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.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Paint.ANTI_ALIAS_FLAG
|
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.semester.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
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.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import io.reactivex.Single
|
import io.reactivex.Maybe
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
@ -48,28 +51,37 @@ class TimetableWidgetFactory(
|
|||||||
override fun onDestroy() {}
|
override fun onDestroy() {}
|
||||||
|
|
||||||
override fun onDataSetChanged() {
|
override fun onDataSetChanged() {
|
||||||
intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) }
|
intent?.extras?.getInt(EXTRA_APPWIDGET_ID)?.let { appWidgetId ->
|
||||||
?.let { date ->
|
val date = LocalDate.ofEpochDay(sharedPref.getLong(getDateWidgetKey(appWidgetId), 0))
|
||||||
try {
|
val studentId = sharedPref.getLong(getStudentWidgetKey(appWidgetId), 0)
|
||||||
lessons = studentRepository.isStudentSaved()
|
|
||||||
.flatMap { isSaved ->
|
lessons = try {
|
||||||
if (isSaved) {
|
studentRepository.isStudentSaved()
|
||||||
studentRepository.getCurrentStudent()
|
.filter { true }
|
||||||
.flatMap { semesterRepository.getCurrentSemester(it) }
|
.flatMap { studentRepository.getSavedStudents().toMaybe() }
|
||||||
.flatMap { timetableRepository.getTimetable(it, date, date) }
|
.flatMap {
|
||||||
} else Single.just(emptyList())
|
if (studentId == 0L) throw IllegalArgumentException("Student id is 0")
|
||||||
}
|
|
||||||
.map { item -> item.sortedBy { it.number } }
|
it.singleOrNull { student -> student.id == studentId }
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.let { student ->
|
||||||
.blockingGet()
|
if (student != null) Maybe.just(student)
|
||||||
} catch (e: Exception) {
|
else Maybe.empty()
|
||||||
Timber.e(e, "An error has occurred while downloading data for the widget")
|
}
|
||||||
}
|
}
|
||||||
|
.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? {
|
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 {
|
return RemoteViews(context.packageName, R.layout.item_widget_timetable).apply {
|
||||||
lessons[position].let {
|
lessons[position].let {
|
@ -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
|
||||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
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.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
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 android.widget.RemoteViews
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
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.services.widgets.TimetableWidgetService
|
||||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
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.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.nextSchoolDay
|
import io.github.wulkanowy.utils.nextSchoolDay
|
||||||
import io.github.wulkanowy.utils.previousSchoolDay
|
import io.github.wulkanowy.utils.previousSchoolDay
|
||||||
|
import io.github.wulkanowy.utils.shortcutWeekDayName
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
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
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TimetableWidgetProvider : BroadcastReceiver() {
|
class TimetableWidgetProvider : BroadcastReceiver() {
|
||||||
@ -32,13 +39,21 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
@Inject
|
@Inject
|
||||||
lateinit var appWidgetManager: AppWidgetManager
|
lateinit var appWidgetManager: AppWidgetManager
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var studentRepository: StudentRepository
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var sharedPref: SharedPrefHelper
|
lateinit var sharedPref: SharedPrefHelper
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var schedulers: SchedulersProvider
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var analytics: FirebaseAnalyticsHelper
|
lateinit var analytics: FirebaseAnalyticsHelper
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
const val EXTRA_FROM_PROVIDER = "extraFromProvider"
|
||||||
|
|
||||||
const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget"
|
const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget"
|
||||||
|
|
||||||
const val EXTRA_BUTTON_TYPE = "extraButtonType"
|
const val EXTRA_BUTTON_TYPE = "extraButtonType"
|
||||||
@ -49,7 +64,9 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
|
|
||||||
const val BUTTON_RESET = "buttonReset"
|
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) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
@ -63,12 +80,14 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
private fun onUpdate(context: Context, intent: Intent) {
|
private fun onUpdate(context: Context, intent: Intent) {
|
||||||
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
if (intent.getStringExtra(EXTRA_BUTTON_TYPE) === null) {
|
||||||
intent.getIntArrayExtra(EXTRA_APPWIDGET_IDS)?.forEach { appWidgetId ->
|
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 {
|
} else {
|
||||||
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
|
val buttonType = intent.getStringExtra(EXTRA_BUTTON_TYPE)
|
||||||
val toggledWidgetId = intent.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)
|
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) {
|
val date = when (buttonType) {
|
||||||
BUTTON_RESET -> now().nextOrSameSchoolDay
|
BUTTON_RESET -> now().nextOrSameSchoolDay
|
||||||
BUTTON_NEXT -> savedDate.nextSchoolDay
|
BUTTON_NEXT -> savedDate.nextSchoolDay
|
||||||
@ -76,35 +95,46 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
else -> now().nextOrSameSchoolDay
|
else -> now().nextOrSameSchoolDay
|
||||||
}
|
}
|
||||||
if (!buttonType.isNullOrBlank()) analytics.logEvent("changed_timetable_widget_day", "button" to buttonType)
|
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) {
|
private fun onDelete(intent: Intent) {
|
||||||
intent.getIntExtra(EXTRA_APPWIDGET_ID, 0).let {
|
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 {
|
RemoteViews(context.packageName, R.layout.widget_timetable).apply {
|
||||||
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
||||||
setTextViewText(R.id.timetableWidgetDay, date.weekDayName.capitalize())
|
setTextViewText(R.id.timetableWidgetDate, "${date.shortcutWeekDayName.capitalize()} ${date.toFormattedString()}")
|
||||||
setTextViewText(R.id.timetableWidgetDate, date.toFormattedString())
|
setTextViewText(R.id.timetableWidgetName, student?.studentName ?: context.getString(R.string.all_no_data))
|
||||||
setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java)
|
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.timetableWidgetNext, createNavIntent(context, appWidgetId, appWidgetId, BUTTON_NEXT))
|
||||||
setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -appWidgetId, appWidgetId, BUTTON_PREV))
|
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.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,
|
setPendingIntentTemplate(R.id.timetableWidgetList,
|
||||||
PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply {
|
PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply {
|
||||||
putExtra(EXTRA_START_MENU_INDEX, 3)
|
putExtra(EXTRA_START_MENU_INDEX, 3)
|
||||||
}, FLAG_UPDATE_CURRENT))
|
}, FLAG_UPDATE_CURRENT))
|
||||||
}.also {
|
}.also {
|
||||||
sharedPref.putLong(createWidgetKey(appWidgetId), date.toEpochDay(), true)
|
sharedPref.putLong(getDateWidgetKey(appWidgetId), date.toEpochDay(), true)
|
||||||
appWidgetManager.apply {
|
appWidgetManager.apply {
|
||||||
notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
|
notifyAppWidgetViewDataChanged(appWidgetId, R.id.timetableWidgetList)
|
||||||
updateAppWidget(appWidgetId, it)
|
updateAppWidget(appWidgetId, it)
|
||||||
@ -120,4 +150,29 @@ class TimetableWidgetProvider : BroadcastReceiver() {
|
|||||||
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
putExtra(EXTRA_TOGGLED_WIDGET_ID, appWidgetId)
|
||||||
}, FLAG_UPDATE_CURRENT)
|
}, 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
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -99,6 +99,9 @@ inline val LocalDate.previousOrSameSchoolDay: LocalDate
|
|||||||
inline val LocalDate.weekDayName: String
|
inline val LocalDate.weekDayName: String
|
||||||
get() = this.format(ofPattern("EEEE", Locale.getDefault()))
|
get() = this.format(ofPattern("EEEE", Locale.getDefault()))
|
||||||
|
|
||||||
|
inline val LocalDate.shortcutWeekDayName: String
|
||||||
|
get() = this.format(ofPattern("EEE", Locale.getDefault()))
|
||||||
|
|
||||||
inline val LocalDate.monday: LocalDate
|
inline val LocalDate.monday: LocalDate
|
||||||
get() = this.with(MONDAY)
|
get() = this.with(MONDAY)
|
||||||
|
|
||||||
|
BIN
app/src/main/res/drawable-hdpi/ic_widget_account.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_widget_account.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 461 B |
BIN
app/src/main/res/drawable-mdpi/ic_widget_account.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_widget_account.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 319 B |
BIN
app/src/main/res/drawable-xhdpi/ic_widget_account.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_widget_account.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 596 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_widget_account.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_widget_account.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 922 B |
Binary file not shown.
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 5.2 KiB |
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="280dp"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/timetableWidgetConfigureTitle"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:paddingStart="24dp"
|
||||||
|
android:paddingLeft="24dp"
|
||||||
|
android:paddingEnd="24dp"
|
||||||
|
android:paddingRight="24dp"
|
||||||
|
android:text="@string/account_title"
|
||||||
|
android:textColor="?android:textColorPrimary"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:firstBaselineToTopHeight="40dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/timetableWidgetConfigureRecycler"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/timetableWidgetConfigureTitle"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:overScrollMode="never"
|
||||||
|
tools:itemCount="3"
|
||||||
|
tools:listitem="@layout/item_account" />
|
||||||
|
</RelativeLayout>
|
@ -33,7 +33,8 @@
|
|||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
tools:text="@tools:sample/lorem/random" />
|
tools:text="@tools:sample/lorem/random"
|
||||||
|
android:textColor="?android:textColorSecondary"/>
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatTextView
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
android:id="@+id/accountItemSchool"
|
android:id="@+id/accountItemSchool"
|
||||||
@ -47,6 +48,7 @@
|
|||||||
android:layout_toRightOf="@id/accountItemImage"
|
android:layout_toRightOf="@id/accountItemImage"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:maxLines="1"
|
android:maxLines="1"
|
||||||
|
android:textColor="?android:textColorSecondary"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
tools:text="@tools:sample/lorem/random" />
|
tools:text="@tools:sample/lorem/random" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
android:background="@drawable/ic_all_divider"
|
android:background="@drawable/ic_all_divider"
|
||||||
android:minHeight="45dp"
|
android:minHeight="45dp"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
tools:context=".ui.widgets.timetable.TimetableWidgetFactory">
|
tools:context=".ui.modules.timetablewidget.TimetableWidgetFactory">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/timetableWidgetItemNumber"
|
android:id="@+id/timetableWidgetItemNumber"
|
||||||
|
@ -4,80 +4,87 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@android:color/white"
|
android:background="@android:color/white"
|
||||||
tools:context=".ui.widgets.timetable.TimetableWidgetProvider">
|
tools:context=".ui.modules.timetablewidget.TimetableWidgetProvider">
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/timetable_widget_bar_height"
|
android:layout_height="56dp"
|
||||||
android:background="@color/colorPrimary">
|
android:background="@color/colorPrimary">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_toStartOf="@id/timetableWidgetAccount"
|
||||||
|
android:layout_toLeftOf="@id/timetableWidgetAccount"
|
||||||
|
android:layout_toEndOf="@id/timetableWidgetNext"
|
||||||
|
android:layout_toRightOf="@id/timetableWidgetNext"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/timetableWidgetDate"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="15sp"
|
||||||
|
tools:text="Pon. 30.03.2019" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/timetableWidgetName"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginLeft="10dp"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
|
android:textSize="13sp"
|
||||||
|
tools:text="Jan Kowalski" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/timetableWidgetAccount"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:background="?android:selectableItemBackground"
|
||||||
|
android:contentDescription="@string/account_title"
|
||||||
|
android:src="@drawable/ic_widget_account" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/timetableWidgetPrev"
|
android:id="@+id/timetableWidgetPrev"
|
||||||
android:layout_width="70dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginStart="5dp"
|
android:layout_marginStart="10dp"
|
||||||
android:layout_marginLeft="5dp"
|
android:layout_marginLeft="10dp"
|
||||||
android:backgroundTint="@color/colorPrimaryDark"
|
android:backgroundTint="@color/colorPrimaryDark"
|
||||||
android:contentDescription="@string/all_prev"
|
android:contentDescription="@string/all_prev"
|
||||||
android:src="@drawable/ic_widget_chevron_24dp"
|
android:src="@drawable/ic_widget_chevron_24dp"
|
||||||
tools:targetApi="lollipop" />
|
tools:targetApi="lollipop" />
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/timetableWidgetDay"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignTop="@+id/timetableWidgetPrev"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_toStartOf="@id/timetableWidgetNext"
|
|
||||||
android:layout_toLeftOf="@id/timetableWidgetNext"
|
|
||||||
android:layout_toEndOf="@id/timetableWidgetPrev"
|
|
||||||
android:layout_toRightOf="@id/timetableWidgetPrev"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="15sp"
|
|
||||||
tools:text="Poniedziałek" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/timetableWidgetDate"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/timetableWidgetDay"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:layout_marginTop="3dp"
|
|
||||||
android:layout_toStartOf="@id/timetableWidgetNext"
|
|
||||||
android:layout_toLeftOf="@id/timetableWidgetNext"
|
|
||||||
android:layout_toEndOf="@id/timetableWidgetPrev"
|
|
||||||
android:layout_toRightOf="@id/timetableWidgetPrev"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:maxLines="1"
|
|
||||||
android:textColor="@android:color/white"
|
|
||||||
android:textSize="14sp"
|
|
||||||
tools:text="12.03.2019" />
|
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/timetableWidgetNext"
|
android:id="@+id/timetableWidgetNext"
|
||||||
android:layout_width="70dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_marginEnd="5dp"
|
android:layout_toEndOf="@id/timetableWidgetPrev"
|
||||||
android:layout_marginRight="5dp"
|
android:layout_toRightOf="@id/timetableWidgetPrev"
|
||||||
android:backgroundTint="@color/colorPrimaryDark"
|
android:backgroundTint="@color/colorPrimaryDark"
|
||||||
android:contentDescription="@string/all_next"
|
android:contentDescription="@string/all_next"
|
||||||
android:rotation="180"
|
android:rotation="180"
|
||||||
android:src="@drawable/ic_widget_chevron_24dp"
|
android:src="@drawable/ic_widget_chevron_24dp"
|
||||||
tools:targetApi="lollipop" />
|
tools:targetApi="lollipop" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<ListView
|
<ListView
|
||||||
android:id="@+id/timetableWidgetList"
|
android:id="@+id/timetableWidgetList"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="@dimen/timetable_widget_bar_height"
|
android:layout_marginTop="56dp"
|
||||||
tools:listitem="@layout/item_widget_timetable" />
|
tools:listitem="@layout/item_widget_timetable" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -24,9 +24,4 @@
|
|||||||
<item name="about_libraries_dividerDark_openSource">@color/about_libraries_dividerDark_openSource_dark</item>
|
<item name="about_libraries_dividerDark_openSource">@color/about_libraries_dividerDark_openSource_dark</item>
|
||||||
<item name="about_libraries_dividerLight_openSource">@color/about_libraries_dividerLight_openSource_dark</item>
|
<item name="about_libraries_dividerLight_openSource">@color/about_libraries_dividerLight_openSource_dark</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style name="WulkanowyTheme.NoActionBar" parent="WulkanowyTheme">
|
|
||||||
<item name="windowActionBar">false</item>
|
|
||||||
<item name="windowNoTitle">true</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -233,8 +233,6 @@
|
|||||||
|
|
||||||
<!--Timetable Widget-->
|
<!--Timetable Widget-->
|
||||||
<string name="widget_timetable_no_items">Brak lekcji</string>
|
<string name="widget_timetable_no_items">Brak lekcji</string>
|
||||||
<string name="widget_timetable_today">Dziś</string>
|
|
||||||
<string name="widget_timetable_tomorrow">Jutro</string>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Preferences-->
|
<!--Preferences-->
|
||||||
|
@ -2,7 +2,4 @@
|
|||||||
<!--BottomNav-->
|
<!--BottomNav-->
|
||||||
<dimen name="bottom_navigation_margin_top_active" tools:override="true">8dp</dimen>
|
<dimen name="bottom_navigation_margin_top_active" tools:override="true">8dp</dimen>
|
||||||
<dimen name="bottom_navigation_margin_top_inactive" tools:override="true">8dp</dimen>
|
<dimen name="bottom_navigation_margin_top_inactive" tools:override="true">8dp</dimen>
|
||||||
|
|
||||||
<!--Timetable Widget-->
|
|
||||||
<dimen name="timetable_widget_bar_height">60dp</dimen>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -218,8 +218,6 @@
|
|||||||
|
|
||||||
<!--Timetable Widget-->
|
<!--Timetable Widget-->
|
||||||
<string name="widget_timetable_no_items">No lessons</string>
|
<string name="widget_timetable_no_items">No lessons</string>
|
||||||
<string name="widget_timetable_today">Today</string>
|
|
||||||
<string name="widget_timetable_tomorrow">Tomorrow</string>
|
|
||||||
|
|
||||||
|
|
||||||
<!--Preferences-->
|
<!--Preferences-->
|
||||||
|
@ -40,4 +40,12 @@
|
|||||||
<style name="WulkanowyTheme.ActionBar" parent="WulkanowyTheme">
|
<style name="WulkanowyTheme.ActionBar" parent="WulkanowyTheme">
|
||||||
<item name="colorControlNormal">@android:color/white</item>
|
<item name="colorControlNormal">@android:color/white</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="WulkanowyTheme.TimetableWidgetAccount" parent="Theme.AppCompat.Light.Dialog">
|
||||||
|
<item name="windowActionBar">false</item>
|
||||||
|
<item name="windowNoTitle">true</item>
|
||||||
|
<item name="android:textColorPrimary">@android:color/primary_text_light</item>
|
||||||
|
<item name="android:textColorSecondary">@android:color/secondary_text_light</item>
|
||||||
|
<item name="android:textColorSecondaryInverse">@android:color/primary_text_dark</item>
|
||||||
|
</style>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:configure="io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetConfigureActivity"
|
||||||
android:initialLayout="@layout/widget_timetable"
|
android:initialLayout="@layout/widget_timetable"
|
||||||
android:minWidth="150dp"
|
android:minWidth="250dp"
|
||||||
android:minHeight="100dp"
|
android:minHeight="110dp"
|
||||||
|
android:minResizeWidth="250dp"
|
||||||
|
android:minResizeHeight="110dp"
|
||||||
android:previewImage="@drawable/img_timetable_widget_preview"
|
android:previewImage="@drawable/img_timetable_widget_preview"
|
||||||
android:resizeMode="horizontal|vertical"
|
android:resizeMode="horizontal|vertical"
|
||||||
android:updatePeriodMillis="3600000"
|
android:updatePeriodMillis="3600000"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user