Compare commits

...

16 Commits

Author SHA1 Message Date
19bc2b8b37 [3.9.10-dev] New UI + stability fixes 2019-11-23 23:26:19 +01:00
673116e27e [Settings/About] Add a new developer to about! 2019-11-23 23:09:03 +01:00
59fcb0a050 [APIv2/Timetable] Add lesson change metadata only when the lesson is today or in the future 2019-11-23 22:40:20 +01:00
cd76f99bbf [APIv2/Timetable] Add showing unread lesson changes 2019-11-23 22:26:21 +01:00
6a4994b9c2 [APIv2/Timetable] Make swipe refresh download timetable for the selected week 2019-11-23 21:57:30 +01:00
63960c5e05 [APIv2/Timetable] Add selecting date, marking as read and fix stepForward in Date 2019-11-23 21:27:52 +01:00
540afb6a28 [Home] Start making new home timetable card in Kotlin 2019-11-23 19:41:55 +01:00
ae10b8abbd [APIv2/Idziennik] Add new timetable getting and fix week start 2019-11-23 19:40:32 +01:00
db2ebab879 [APIv2/Vulcan] Add missing Lublin endpoints 2019-11-23 19:39:13 +01:00
6ec3d062df [UI] Update header image. Fix fragment bundle passing. 2019-11-23 19:37:00 +01:00
86b6060a09 [UI] Migrate to outlined icons. 2019-11-23 18:32:18 +01:00
83d123e341 [UI] New notifications view. 2019-11-22 22:41:40 +01:00
34061695f9 [UI] Update colored placeholder icons. 2019-11-22 19:23:49 +01:00
de68476442 [UI/Event] Add Sync text to manual event dialog. 2019-11-22 18:42:45 +01:00
678a81a44b [APIv2/Vulcan] Improve Vulcan login when migrating from APIv1. 2019-11-22 18:42:11 +01:00
cfb3096d53 [Sync] Add better task cancelling and better frozen task detection. 2019-11-22 18:41:15 +01:00
61 changed files with 1019 additions and 738 deletions

2
.gitignore vendored
View File

@ -81,3 +81,5 @@ lint/generated/
lint/outputs/ lint/outputs/
lint/tmp/ lint/tmp/
# lint/reports/ # lint/reports/
app/schemas/

View File

@ -17,6 +17,7 @@ import android.util.LongSparseArray
import android.util.SparseArray import android.util.SparseArray
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import android.widget.CompoundButton
import android.widget.TextView import android.widget.TextView
import androidx.annotation.* import androidx.annotation.*
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
@ -441,6 +442,13 @@ inline fun <T : View> T.onClick(crossinline onClickListener: (v: T) -> Unit) {
} }
} }
@Suppress("UNCHECKED_CAST")
inline fun <T : CompoundButton> T.onChange(crossinline onChangeListener: (v: T, isChecked: Boolean) -> Unit) {
setOnCheckedChangeListener { buttonView, isChecked ->
onChangeListener(buttonView as T, isChecked)
}
}
fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) { fun <T> LiveData<T>.observeOnce(lifecycleOwner: LifecycleOwner, observer: Observer<T>) {
observe(lifecycleOwner, object : Observer<T> { observe(lifecycleOwner, object : Observer<T> {
override fun onChanged(t: T?) { override fun onChanged(t: T?) {

View File

@ -124,7 +124,7 @@ class MainActivity : AppCompatActivity() {
// home item // home item
list += NavTarget(DRAWER_ITEM_HOME, R.string.menu_home_page, HomeFragment::class) list += NavTarget(DRAWER_ITEM_HOME, R.string.menu_home_page, HomeFragment::class)
.withTitle(R.string.app_name) .withTitle(R.string.app_name)
.withIcon(CommunityMaterial.Icon2.cmd_home) .withIcon(CommunityMaterial.Icon2.cmd_home_outline)
.isInDrawer(true) .isInDrawer(true)
.isStatic(true) .isStatic(true)
.withPopToHome(false) .withPopToHome(false)
@ -135,50 +135,50 @@ class MainActivity : AppCompatActivity() {
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_AGENDA, R.string.menu_agenda, AgendaFragment::class) list += NavTarget(DRAWER_ITEM_AGENDA, R.string.menu_agenda, AgendaFragment::class)
.withIcon(CommunityMaterial.Icon.cmd_calendar) .withIcon(CommunityMaterial.Icon.cmd_calendar_outline)
.withBadgeTypeId(TYPE_EVENT) .withBadgeTypeId(TYPE_EVENT)
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_GRADES, R.string.menu_grades, GradesFragment::class) list += NavTarget(DRAWER_ITEM_GRADES, R.string.menu_grades, GradesFragment::class)
.withIcon(CommunityMaterial.Icon2.cmd_numeric_5_box) .withIcon(CommunityMaterial.Icon2.cmd_numeric_5_box_outline)
.withBadgeTypeId(TYPE_GRADE) .withBadgeTypeId(TYPE_GRADE)
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_MESSAGES, R.string.menu_messages, MessagesFragment::class) list += NavTarget(DRAWER_ITEM_MESSAGES, R.string.menu_messages, MessagesFragment::class)
.withIcon(CommunityMaterial.Icon.cmd_email) .withIcon(CommunityMaterial.Icon.cmd_email_outline)
.withBadgeTypeId(TYPE_MESSAGE) .withBadgeTypeId(TYPE_MESSAGE)
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_HOMEWORK, R.string.menu_homework, HomeworkFragment::class) list += NavTarget(DRAWER_ITEM_HOMEWORK, R.string.menu_homework, HomeworkFragment::class)
.withIcon(SzkolnyFont.Icon.szf_file_document_edit) .withIcon(SzkolnyFont.Icon.szf_notebook_outline)
.withBadgeTypeId(TYPE_HOMEWORK) .withBadgeTypeId(TYPE_HOMEWORK)
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_BEHAVIOUR, R.string.menu_notices, BehaviourFragment::class) list += NavTarget(DRAWER_ITEM_BEHAVIOUR, R.string.menu_notices, BehaviourFragment::class)
.withIcon(CommunityMaterial.Icon2.cmd_message_alert) .withIcon(CommunityMaterial.Icon.cmd_emoticon_outline)
.withBadgeTypeId(TYPE_NOTICE) .withBadgeTypeId(TYPE_NOTICE)
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_ATTENDANCE, R.string.menu_attendance, AttendanceFragment::class) list += NavTarget(DRAWER_ITEM_ATTENDANCE, R.string.menu_attendance, AttendanceFragment::class)
.withIcon(CommunityMaterial.Icon.cmd_calendar_remove) .withIcon(CommunityMaterial.Icon.cmd_calendar_remove_outline)
.withBadgeTypeId(TYPE_ATTENDANCE) .withBadgeTypeId(TYPE_ATTENDANCE)
.isInDrawer(true) .isInDrawer(true)
list += NavTarget(DRAWER_ITEM_ANNOUNCEMENTS, R.string.menu_announcements, AnnouncementsFragment::class) list += NavTarget(DRAWER_ITEM_ANNOUNCEMENTS, R.string.menu_announcements, AnnouncementsFragment::class)
.withIcon(CommunityMaterial.Icon.cmd_bulletin_board) .withIcon(CommunityMaterial.Icon.cmd_bullhorn_outline)
.withBadgeTypeId(TYPE_ANNOUNCEMENT) .withBadgeTypeId(TYPE_ANNOUNCEMENT)
.isInDrawer(true) .isInDrawer(true)
// static drawer items // static drawer items
list += NavTarget(DRAWER_ITEM_NOTIFICATIONS, R.string.menu_notifications, NotificationsFragment::class) list += NavTarget(DRAWER_ITEM_NOTIFICATIONS, R.string.menu_notifications, NotificationsFragment::class)
.withIcon(CommunityMaterial.Icon.cmd_bell_ring) .withIcon(CommunityMaterial.Icon.cmd_bell_ring_outline)
.isInDrawer(true) .isInDrawer(true)
.isStatic(true) .isStatic(true)
.isBelowSeparator(true) .isBelowSeparator(true)
list += NavTarget(DRAWER_ITEM_SETTINGS, R.string.menu_settings, SettingsNewFragment::class) list += NavTarget(DRAWER_ITEM_SETTINGS, R.string.menu_settings, SettingsNewFragment::class)
.withIcon(CommunityMaterial.Icon2.cmd_settings) .withIcon(CommunityMaterial.Icon2.cmd_settings_outline)
.isInDrawer(true) .isInDrawer(true)
.isStatic(true) .isStatic(true)
.isBelowSeparator(true) .isBelowSeparator(true)
@ -197,7 +197,7 @@ class MainActivity : AppCompatActivity() {
.isInProfileList(false) .isInProfileList(false)
list += NavTarget(DRAWER_PROFILE_SYNC_ALL, R.string.menu_sync_all, null) list += NavTarget(DRAWER_PROFILE_SYNC_ALL, R.string.menu_sync_all, null)
.withIcon(CommunityMaterial.Icon2.cmd_sync) .withIcon(CommunityMaterial.Icon.cmd_download_outline)
.isInProfileList(true) .isInProfileList(true)
@ -434,7 +434,7 @@ class MainActivity : AppCompatActivity() {
navView.coordinator.postDelayed({ navView.coordinator.postDelayed({
CafeBar.builder(this) CafeBar.builder(this)
.content(R.string.rate_snackbar_text) .content(R.string.rate_snackbar_text)
.icon(IconicsDrawable(this).icon(CommunityMaterial.Icon2.cmd_star).size(IconicsSize.dp(20)).color(IconicsColor.colorInt(Themes.getPrimaryTextColor(this)))) .icon(IconicsDrawable(this).icon(CommunityMaterial.Icon2.cmd_star_outline).size(IconicsSize.dp(20)).color(IconicsColor.colorInt(Themes.getPrimaryTextColor(this))))
.positiveText(R.string.rate_snackbar_positive) .positiveText(R.string.rate_snackbar_positive)
.positiveColor(-0xb350b0) .positiveColor(-0xb350b0)
.negativeText(R.string.rate_snackbar_negative) .negativeText(R.string.rate_snackbar_negative)
@ -471,7 +471,7 @@ class MainActivity : AppCompatActivity() {
bottomSheet.appendItems( bottomSheet.appendItems(
BottomSheetPrimaryItem(false) BottomSheetPrimaryItem(false)
.withTitle(R.string.menu_sync) .withTitle(R.string.menu_sync)
.withIcon(CommunityMaterial.Icon2.cmd_sync) .withIcon(CommunityMaterial.Icon.cmd_download_outline)
.withOnClickListener(View.OnClickListener { .withOnClickListener(View.OnClickListener {
bottomSheet.close() bottomSheet.close()
SyncViewListDialog(this, navTargetId) SyncViewListDialog(this, navTargetId)
@ -479,17 +479,17 @@ class MainActivity : AppCompatActivity() {
BottomSheetSeparatorItem(false), BottomSheetSeparatorItem(false),
BottomSheetPrimaryItem(false) BottomSheetPrimaryItem(false)
.withTitle(R.string.menu_settings) .withTitle(R.string.menu_settings)
.withIcon(CommunityMaterial.Icon2.cmd_settings) .withIcon(CommunityMaterial.Icon2.cmd_settings_outline)
.withOnClickListener(View.OnClickListener { loadTarget(DRAWER_ITEM_SETTINGS) }), .withOnClickListener(View.OnClickListener { loadTarget(DRAWER_ITEM_SETTINGS) }),
BottomSheetPrimaryItem(false) BottomSheetPrimaryItem(false)
.withTitle(R.string.menu_feedback) .withTitle(R.string.menu_feedback)
.withIcon(CommunityMaterial.Icon2.cmd_help_circle) .withIcon(CommunityMaterial.Icon2.cmd_help_circle_outline)
.withOnClickListener(View.OnClickListener { loadTarget(TARGET_FEEDBACK) }) .withOnClickListener(View.OnClickListener { loadTarget(TARGET_FEEDBACK) })
) )
if (App.devMode) { if (App.devMode) {
bottomSheet += BottomSheetPrimaryItem(false) bottomSheet += BottomSheetPrimaryItem(false)
.withTitle(R.string.menu_debug) .withTitle(R.string.menu_debug)
.withIcon(CommunityMaterial.Icon.cmd_android_debug_bridge) .withIcon(CommunityMaterial.Icon.cmd_android_studio)
.withOnClickListener(View.OnClickListener { loadTarget(DRAWER_ITEM_DEBUG) }) .withOnClickListener(View.OnClickListener { loadTarget(DRAWER_ITEM_DEBUG) })
} }
@ -537,9 +537,16 @@ class MainActivity : AppCompatActivity() {
DRAWER_ITEM_MESSAGES -> MessagesFragment.pageSelection DRAWER_ITEM_MESSAGES -> MessagesFragment.pageSelection
else -> 0 else -> 0
} }
val arguments = when (navTargetId) {
DRAWER_ITEM_TIMETABLE -> JsonObject().apply {
addProperty("weekStart", TimetableFragment.pageSelection?.weekStart?.stringY_m_d)
}
else -> null
}
EdziennikTask.syncProfile( EdziennikTask.syncProfile(
App.profileId, App.profileId,
listOf(navTargetId to fragmentParam) listOf(navTargetId to fragmentParam),
arguments
).enqueue(this) ).enqueue(this)
} }
@Subscribe(threadMode = ThreadMode.MAIN) @Subscribe(threadMode = ThreadMode.MAIN)
@ -694,10 +701,10 @@ class MainActivity : AppCompatActivity() {
app.profile == null -> { app.profile == null -> {
if (intentProfileId == -1) if (intentProfileId == -1)
intentProfileId = app.appSharedPrefs.getInt("current_profile_id", 1) intentProfileId = app.appSharedPrefs.getInt("current_profile_id", 1)
loadProfile(intentProfileId, intentTargetId) loadProfile(intentProfileId, intentTargetId, extras)
} }
intentProfileId != -1 -> { intentProfileId != -1 -> {
loadProfile(intentProfileId, intentTargetId) loadProfile(intentProfileId, intentTargetId, extras)
} }
intentTargetId != -1 -> { intentTargetId != -1 -> {
drawer.currentProfile = app.profile.id drawer.currentProfile = app.profile.id

View File

@ -87,7 +87,7 @@ class WidgetTimetable : AppWidgetProvider() {
.colorInt(Color.WHITE) .colorInt(Color.WHITE)
.sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap()) .sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap())
views.setImageViewBitmap(R.id.widgetTimetableSync, IconicsDrawable(context, CommunityMaterial.Icon2.cmd_sync) views.setImageViewBitmap(R.id.widgetTimetableSync, IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline)
.colorInt(Color.WHITE) .colorInt(Color.WHITE)
.sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap()) .sizeDp(if (widgetConfig.bigStyle) 24 else 16).toBitmap())

View File

@ -60,6 +60,9 @@ class ApiService : Service() {
private val notification by lazy { EdziennikNotification(this) } private val notification by lazy { EdziennikNotification(this) }
private var lastEventTime = System.currentTimeMillis()
private var taskCancelTries = 0
/* ______ _ _ _ _ _____ _ _ _ _ /* ______ _ _ _ _ _____ _ _ _ _
| ____| | | (_) (_) | / ____| | | | | | | | ____| | | (_) (_) | / ____| | | | | | |
| |__ __| |_____ ___ _ __ _ __ _| | __ | | __ _| | | |__ __ _ ___| | __ | |__ __| |_____ ___ _ __ _ __ _| | __ | | __ _| | | |__ __ _ ___| | __
@ -68,22 +71,17 @@ class ApiService : Service() {
|______\__,_/___|_|\___|_| |_|_| |_|_|_|\_\ \_____\__,_|_|_|_.__/ \__,_|\___|_|\*/ |______\__,_/___|_|\___|_| |_|_| |_|_|_|\_\ \_____\__,_|_|_|_.__/ \__,_|\___|_|\*/
private val taskCallback = object : EdziennikCallback { private val taskCallback = object : EdziennikCallback {
override fun onCompleted() { override fun onCompleted() {
lastEventTime = System.currentTimeMillis()
d(TAG, "Task $taskRunningId (profile $taskProfileId) - $taskProgressText - finished") d(TAG, "Task $taskRunningId (profile $taskProfileId) - $taskProgressText - finished")
//if (!taskCancelled) { EventBus.getDefault().post(ApiTaskFinishedEvent(taskProfileId))
EventBus.getDefault().post(ApiTaskFinishedEvent(taskProfileId)) clearTask()
//}
taskIsRunning = false
taskRunningId = -1
taskRunning = null
taskProfileId = -1
taskProgress = -1f
taskProgressText = null
notification.setIdle().post() notification.setIdle().post()
runTask() runTask()
} }
override fun onError(apiError: ApiError) { override fun onError(apiError: ApiError) {
lastEventTime = System.currentTimeMillis()
d(TAG, "Task $taskRunningId threw an error - $apiError") d(TAG, "Task $taskRunningId threw an error - $apiError")
apiError.profileId = taskProfileId apiError.profileId = taskProfileId
EventBus.getDefault().post(ApiTaskErrorEvent(apiError)) EventBus.getDefault().post(ApiTaskErrorEvent(apiError))
@ -92,9 +90,7 @@ class ApiService : Service() {
if (apiError.isCritical) { if (apiError.isCritical) {
taskRunning?.cancel() taskRunning?.cancel()
notification.setCriticalError().post() notification.setCriticalError().post()
taskRunning = null clearTask()
taskIsRunning = false
taskRunningId = -1
runTask() runTask()
} }
else { else {
@ -103,6 +99,7 @@ class ApiService : Service() {
} }
override fun onProgress(step: Float) { override fun onProgress(step: Float) {
lastEventTime = System.currentTimeMillis()
if (step <= 0) if (step <= 0)
return return
if (taskProgress < 0) if (taskProgress < 0)
@ -115,6 +112,7 @@ class ApiService : Service() {
} }
override fun onStartProgress(stringRes: Int) { override fun onStartProgress(stringRes: Int) {
lastEventTime = System.currentTimeMillis()
taskProgressText = getString(stringRes) taskProgressText = getString(stringRes)
d(TAG, "Task $taskRunningId progress: $taskProgressText") d(TAG, "Task $taskRunningId progress: $taskProgressText")
EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText)) EventBus.getDefault().post(ApiTaskProgressEvent(taskProfileId, taskProgress, taskProgressText))
@ -129,6 +127,7 @@ class ApiService : Service() {
| | (_| \__ \ < | __/> < __/ (__| |_| | |_| | (_) | | | | | | (_| \__ \ < | __/> < __/ (__| |_| | |_| | (_) | | | |
|_|\__,_|___/_|\_\ \___/_/\_\___|\___|\__,_|\__|_|\___/|_| |*/ |_|\__,_|___/_|\_\ \___/_/\_\___|\___|\__,_|\__|_|\___/|_| |*/
private fun runTask() { private fun runTask() {
checkIfTaskFrozen()
if (taskIsRunning) if (taskIsRunning)
return return
if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && finishingTaskQueue.isEmpty())) { if (taskCancelled || serviceClosed || (taskQueue.isEmpty() && finishingTaskQueue.isEmpty())) {
@ -137,6 +136,8 @@ class ApiService : Service() {
return return
} }
lastEventTime = System.currentTimeMillis()
val task = if (taskQueue.isEmpty()) finishingTaskQueue.removeAt(0) else taskQueue.removeAt(0) val task = if (taskQueue.isEmpty()) finishingTaskQueue.removeAt(0) else taskQueue.removeAt(0)
task.taskId = ++taskMaximumId task.taskId = ++taskMaximumId
task.prepare(app) task.prepare(app)
@ -166,6 +167,48 @@ class ApiService : Service() {
} }
} }
/**
* Check if a task is inactive for more than 30 seconds.
* If the user tries to cancel a task with no success at least three times,
* consider it frozen as well.
*
* This usually means it is broken and won't become active again.
* This method cancels the task and removes any pointers to it.
*/
private fun checkIfTaskFrozen(): Boolean {
if (System.currentTimeMillis() - lastEventTime > 30*1000
|| taskCancelTries >= 3) {
val time = System.currentTimeMillis() - lastEventTime
d(TAG, "!!! Task $taskRunningId froze for $time ms. $taskRunning")
clearTask()
return true
}
return false
}
/**
* Stops the service if the current task is frozen/broken.
*/
private fun stopIfTaskFrozen() {
if (checkIfTaskFrozen()) {
stopSelf()
}
}
/**
* Remove any task descriptors or pointers from the service.
*/
private fun clearTask() {
taskIsRunning = false
taskRunningId = -1
taskRunning = null
taskProfileId = -1
taskProgress = -1f
taskProgressText = null
taskCancelled = false
taskCancelTries = 0
}
private fun allCompleted() { private fun allCompleted() {
EventBus.getDefault().post(ApiTaskAllFinishedEvent()) EventBus.getDefault().post(ApiTaskAllFinishedEvent())
stopSelf() stopSelf()
@ -211,8 +254,10 @@ class ApiService : Service() {
EventBus.getDefault().removeStickyEvent(request) EventBus.getDefault().removeStickyEvent(request)
d(TAG, request.toString()) d(TAG, request.toString())
taskCancelTries++
taskCancelled = true taskCancelled = true
taskRunning?.cancel() taskRunning?.cancel()
stopIfTaskFrozen()
} }
@Subscribe(sticky = true, threadMode = ThreadMode.ASYNC) @Subscribe(sticky = true, threadMode = ThreadMode.ASYNC)
fun onServiceCloseRequest(request: ServiceCloseRequest) { fun onServiceCloseRequest(request: ServiceCloseRequest) {

View File

@ -138,10 +138,12 @@ class DataIdziennik(app: App, profile: Profile?, loginStore: LoginStore) : Data(
val teacher = teacherList.singleOrNull { it.fullName == "$firstName $lastName" } val teacher = teacherList.singleOrNull { it.fullName == "$firstName $lastName" }
return validateTeacher(teacher, firstName, lastName) return validateTeacher(teacher, firstName, lastName)
} }
fun getTeacher(firstNameChar: Char, lastName: String): Teacher { fun getTeacher(firstNameChar: Char, lastName: String): Teacher {
val teacher = teacherList.singleOrNull { it.shortName == "$firstNameChar.$lastName" } val teacher = teacherList.singleOrNull { it.shortName == "$firstNameChar.$lastName" }
return validateTeacher(teacher, firstNameChar.toString(), lastName) return validateTeacher(teacher, firstNameChar.toString(), lastName)
} }
fun getTeacherByLastFirst(nameLastFirst: String): Teacher { fun getTeacherByLastFirst(nameLastFirst: String): Teacher {
val nameParts = nameLastFirst.split(" ") val nameParts = nameLastFirst.split(" ")
return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[1], nameParts[0]) return if (nameParts.size == 1) getTeacher(nameParts[0], "") else getTeacher(nameParts[1], nameParts[0])

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) Kuba Szczodrzyński 2019-10-27. * Copyright (c) Kacper Ziubryniewicz 2019-11-22
*/ */
package pl.szczodrzynski.edziennik.api.v2.idziennik.data.web package pl.szczodrzynski.edziennik.api.v2.idziennik.data.web
@ -12,33 +12,38 @@ import pl.szczodrzynski.edziennik.api.v2.idziennik.DataIdziennik
import pl.szczodrzynski.edziennik.api.v2.idziennik.ENDPOINT_IDZIENNIK_WEB_TIMETABLE import pl.szczodrzynski.edziennik.api.v2.idziennik.ENDPOINT_IDZIENNIK_WEB_TIMETABLE
import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikWeb import pl.szczodrzynski.edziennik.api.v2.idziennik.data.IdziennikWeb
import pl.szczodrzynski.edziennik.api.v2.models.ApiError import pl.szczodrzynski.edziennik.api.v2.models.ApiError
import pl.szczodrzynski.edziennik.api.v2.models.DataRemoveModel
import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS import pl.szczodrzynski.edziennik.data.db.modules.api.SYNC_ALWAYS
import pl.szczodrzynski.edziennik.data.db.modules.lessons.Lesson
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange.TYPE_CANCELLED
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange.TYPE_CHANGE
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonRange import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonRange
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week import pl.szczodrzynski.edziennik.utils.models.Week
class IdziennikWebTimetable(override val data: DataIdziennik, class IdziennikWebTimetable(override val data: DataIdziennik,
val onSuccess: () -> Unit) : IdziennikWeb(data) { val onSuccess: () -> Unit) : IdziennikWeb(data) {
companion object { companion object {
private const val TAG = "IdziennikWebTimetable" private const val TAG = "IdziennikWebTimetable"
} }
init { init {
val weekStart = Week.getWeekStart() val currentWeekStart = Week.getWeekStart()
if (Date.getToday().weekDay > 4) { if (Date.getToday().weekDay > 4) {
weekStart.stepForward(0, 0, 7) currentWeekStart.stepForward(0, 0, 7)
} }
val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d
val weekStart = Date.fromY_m_d(getDate)
val weekEnd = weekStart.clone().stepForward(0, 0, 6)
webApiGet(TAG, IDZIENNIK_WEB_TIMETABLE, mapOf( webApiGet(TAG, IDZIENNIK_WEB_TIMETABLE, mapOf(
"idPozDziennika" to data.registerId, "idPozDziennika" to data.registerId,
"pidRokSzkolny" to data.schoolYearId, "pidRokSzkolny" to data.schoolYearId,
"data" to weekStart.stringY_m_d+"T10:00:00.000Z" "data" to "${weekStart.stringY_m_d}T10:00:00.000Z"
)) { result -> )) { result ->
val json = result.getJsonObject("d") ?: run { val json = result.getJsonObject("d") ?: run {
data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA) data.error(ApiError(TAG, ERROR_IDZIENNIK_WEB_REQUEST_NO_DATA)
@ -56,64 +61,103 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
data.lessonRanges[lessonRange.lessonNumber] = lessonRange data.lessonRanges[lessonRange.lessonNumber] = lessonRange
} }
val dates = mutableSetOf<Int>()
val lessons = mutableListOf<Lesson>()
json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { lesson -> json.getJsonArray("Przedmioty")?.asJsonObjectList()?.forEach { lesson ->
val subject = data.getSubject( val subject = data.getSubject(
lesson.getString("Nazwa") ?: return@forEach, lesson.getString("Nazwa") ?: return@forEach,
lesson.getLong("Id"), lesson.getLong("Id"),
lesson.getString("Skrot") ?: "" lesson.getString("Skrot") ?: ""
) )
val teacher = data.getTeacherByFDotLast(lesson.getString("Nauczyciel") ?: return@forEach) val teacher = data.getTeacherByFDotLast(lesson.getString("Nauczyciel")
val weekDay = lesson.getInt("DzienTygodnia")?.minus(1) ?: return@forEach ?: return@forEach)
val lessonRange = data.lessonRanges[lesson.getInt("Godzina")?.plus(1) ?: return@forEach]
val lessonObject = Lesson( val newSubjectName = lesson.getString("PrzedmiotZastepujacy")
profileId, val newSubject = when (newSubjectName.isNullOrBlank()) {
weekDay, true -> null
lessonRange.startTime, else -> data.getSubject(newSubjectName, null, newSubjectName)
lessonRange.endTime
).apply {
subjectId = subject.id
teacherId = teacher.id
teamId = data.teamClass?.id ?: -1
classroomName = lesson.getString("NazwaSali") ?: ""
} }
data.lessonList.add(lessonObject) val newTeacherName = lesson.getString("NauZastepujacy")
val newTeacher = when (newTeacherName.isNullOrBlank()) {
true -> null
else -> data.getTeacherByFDotLast(newTeacherName)
}
val weekDay = lesson.getInt("DzienTygodnia")?.minus(1) ?: return@forEach
val lessonRange = data.lessonRanges[lesson.getInt("Godzina")?.plus(1)
?: return@forEach]
val lessonDate = weekStart.clone().stepForward(0, 0, weekDay)
val classroom = lesson.getString("NazwaSali")
val id = lessonDate.combineWith(lessonRange.startTime) / 6L * 10L + (lesson.hashCode() and 0xFFFF)
val type = lesson.getInt("TypZastepstwa") ?: -1 val type = lesson.getInt("TypZastepstwa") ?: -1
if (type != -1) {
// we have a lesson change to process
val lessonChangeObject = LessonChange(
profileId,
weekStart.clone().stepForward(0, 0, weekDay),
lessonObject.startTime,
lessonObject.endTime
)
lessonChangeObject.teamId = lessonObject.teamId val lessonObject = Lesson(profileId, id)
lessonChangeObject.teacherId = lessonObject.teacherId
lessonChangeObject.subjectId = lessonObject.subjectId when (type) {
lessonChangeObject.classroomName = lessonObject.classroomName 1, 2, 3, 4, 5 -> {
when (type) { lessonObject.apply {
0 -> lessonChangeObject.type = TYPE_CANCELLED this.type = Lesson.TYPE_CHANGE
1, 2, 3, 4, 5 -> {
lessonChangeObject.type = TYPE_CHANGE this.date = lessonDate
val newTeacher = lesson.getString("NauZastepujacy") this.lessonNumber = lessonRange.lessonNumber
val newSubject = lesson.getString("PrzedmiotZastepujacy") this.startTime = lessonRange.startTime
if (newTeacher != null) { this.endTime = lessonRange.endTime
lessonChangeObject.teacherId = data.getTeacherByFDotLast(newTeacher).id this.subjectId = newSubject?.id
} this.teacherId = newTeacher?.id
if (newSubject != null) { this.teamId = data.teamClass?.id
lessonChangeObject.subjectId = data.getSubject(newSubject, null, "").id this.classroom = classroom
}
this.oldDate = lessonDate
this.oldLessonNumber = lessonRange.lessonNumber
this.oldStartTime = lessonRange.startTime
this.oldEndTime = lessonRange.endTime
this.oldSubjectId = subject.id
this.oldTeacherId = teacher.id
this.oldTeamId = data.teamClass?.id
this.oldClassroom = classroom
} }
} }
0 -> {
lessonObject.apply {
this.type = Lesson.TYPE_CANCELLED
data.lessonChangeList.add(lessonChangeObject) this.oldDate = lessonDate
this.oldLessonNumber = lessonRange.lessonNumber
this.oldStartTime = lessonRange.startTime
this.oldEndTime = lessonRange.endTime
this.oldSubjectId = subject.id
this.oldTeacherId = teacher.id
this.oldTeamId = data.teamClass?.id
this.oldClassroom = classroom
}
}
else -> {
lessonObject.apply {
this.type = Lesson.TYPE_NORMAL
this.date = lessonDate
this.lessonNumber = lessonRange.lessonNumber
this.startTime = lessonRange.startTime
this.endTime = lessonRange.endTime
this.subjectId = subject.id
this.teacherId = teacher.id
this.teamId = data.teamClass?.id
this.classroom = classroom
}
}
}
dates.add(lessonDate.value)
lessons.add(lessonObject)
if (lessonObject.type != Lesson.TYPE_NORMAL && lessonDate >= Date.getToday()) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,
lessonChangeObject.id, lessonObject.id,
profile?.empty ?: false, profile?.empty ?: false,
profile?.empty ?: false, profile?.empty ?: false,
System.currentTimeMillis() System.currentTimeMillis()
@ -121,6 +165,23 @@ class IdziennikWebTimetable(override val data: DataIdziennik,
} }
} }
val date: Date = weekStart.clone()
while (date <= weekEnd) {
if (!dates.contains(date.value)) {
lessons.add(Lesson(profileId, date.value.toLong()).apply {
this.type = Lesson.TYPE_NO_LESSONS
this.date = date.clone()
})
}
date.stepForward(0, 0, 1)
}
d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate")
data.lessonNewList.addAll(lessons)
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS) data.setSyncNext(ENDPOINT_IDZIENNIK_WEB_TIMETABLE, SYNC_ALWAYS)
onSuccess() onSuccess()
} }

View File

@ -17,6 +17,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time import pl.szczodrzynski.edziennik.utils.models.Time
import pl.szczodrzynski.edziennik.utils.models.Week
class LibrusApiTimetables(override val data: DataLibrus, class LibrusApiTimetables(override val data: DataLibrus,
val onSuccess: () -> Unit) : LibrusApi(data) { val onSuccess: () -> Unit) : LibrusApi(data) {
@ -29,9 +30,18 @@ class LibrusApiTimetables(override val data: DataLibrus,
data.db.classroomDao().getAllNow(profileId).toSparseArray(data.classrooms) { it.id } data.db.classroomDao().getAllNow(profileId).toSparseArray(data.classrooms) { it.id }
} }
val currentWeekStart = Date.getToday().let { it.stepForward(0, 0, -it.weekDay) } val currentWeekStart = Week.getWeekStart()
if (Date.getToday().weekDay > 4) {
currentWeekStart.stepForward(0, 0, 7)
}
val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d
apiGet(TAG, "Timetables?weekStart=$getDate") { json ->
val weekStart = Date.fromY_m_d(getDate)
val weekEnd = weekStart.clone().stepForward(0, 0, 6)
apiGet(TAG, "Timetables?weekStart=${weekStart.stringY_m_d}") { json ->
val days = json.getJsonObject("Timetable") val days = json.getJsonObject("Timetable")
days?.entrySet()?.forEach { (dateString, dayEl) -> days?.entrySet()?.forEach { (dateString, dayEl) ->
@ -57,8 +67,6 @@ class LibrusApiTimetables(override val data: DataLibrus,
} }
} }
val weekStart = Date.fromY_m_d(getDate)
val weekEnd = weekStart.clone().stepForward(0, 0, 6)
d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate") d(TAG, "Clearing lessons between ${weekStart.stringY_m_d} and ${weekEnd.stringY_m_d} - timetable downloaded for $getDate")
data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd)) data.toRemove.add(DataRemoveModel.Timetable.between(weekStart, weekEnd))
@ -176,7 +184,7 @@ class LibrusApiTimetables(override val data: DataLibrus,
} }
} }
if (lessonObject.type != Lesson.TYPE_NORMAL) { if (lessonObject.type != Lesson.TYPE_NORMAL && lessonDate >= Date.getToday()) {
data.metadataList.add( data.metadataList.add(
Metadata( Metadata(
data.profileId, data.profileId,

View File

@ -75,7 +75,7 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List<String>) {
} }
} }
if (it.type != Lesson.TYPE_NORMAL) { if (it.type != Lesson.TYPE_NORMAL && date >= Date.getToday()) {
data.metadataList.add( data.metadataList.add(
Metadata( Metadata(
data.profileId, data.profileId,
@ -195,4 +195,4 @@ class MobidziennikApiTimetable(val data: DataMobidziennik, rows: List<String>) {
} }
}*/ }*/
} }
} }

View File

@ -164,6 +164,8 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
"GD1" -> "https://uonetplus-komunikacja.edu.gdansk.pl" "GD1" -> "https://uonetplus-komunikacja.edu.gdansk.pl"
"KA1" -> "https://uonetplus-komunikacja.mcuw.katowice.eu" "KA1" -> "https://uonetplus-komunikacja.mcuw.katowice.eu"
"KA2" -> "https://uonetplus-komunikacja-test.mcuw.katowice.eu" "KA2" -> "https://uonetplus-komunikacja-test.mcuw.katowice.eu"
"LU1" -> "https://uonetplus-komunikacja.edu.lublin.eu"
"LU2" -> "https://test-uonetplus-komunikacja.edu.lublin.eu"
"P03" -> "https://efeb-komunikacja-pro-efebmobile.pro.vulcan.pl" "P03" -> "https://efeb-komunikacja-pro-efebmobile.pro.vulcan.pl"
"P01" -> "http://efeb-komunikacja.pro-hudson.win.vulcan.pl" "P01" -> "http://efeb-komunikacja.pro-hudson.win.vulcan.pl"
"P02" -> "http://efeb-komunikacja.pro-hudsonrc.win.vulcan.pl" "P02" -> "http://efeb-komunikacja.pro-hudsonrc.win.vulcan.pl"
@ -172,7 +174,7 @@ class DataVulcan(app: App, profile: Profile?, loginStore: LoginStore) : Data(app
"SZ9" -> "http://vulcan.szkolny.eu" "SZ9" -> "http://vulcan.szkolny.eu"
else -> null else -> null
} }
return if (url != null) "$url/$symbol" else null return if (url != null) "$url/$symbol" else loginStore.getLoginData("apiUrl", null)
} }
val fullApiUrl: String? val fullApiUrl: String?

View File

@ -20,6 +20,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
import pl.szczodrzynski.edziennik.utils.Utils.crc16 import pl.szczodrzynski.edziennik.utils.Utils.crc16
import pl.szczodrzynski.edziennik.utils.Utils.d import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Week
class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Unit) : VulcanApi(data) { class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Unit) : VulcanApi(data) {
companion object { companion object {
@ -27,10 +28,15 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
} }
init { data.profile?.also { profile -> init { data.profile?.also { profile ->
val currentWeekStart = Date.getToday().let { it.stepForward(0, 0, -it.weekDay) } val currentWeekStart = Week.getWeekStart()
val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d val getDate = data.arguments?.getString("weekStart") ?: currentWeekStart.stringY_m_d
val weekStart = Date.fromY_m_d(getDate) val weekStart = Date.fromY_m_d(getDate)
if (Date.getToday().weekDay > 4 && weekStart == currentWeekStart) {
weekStart.stepForward(0, 0, 7)
}
val weekEnd = weekStart.clone().stepForward(0, 0, 6) val weekEnd = weekStart.clone().stepForward(0, 0, 6)
apiGet(TAG, VULCAN_API_ENDPOINT_TIMETABLE, parameters = mapOf( apiGet(TAG, VULCAN_API_ENDPOINT_TIMETABLE, parameters = mapOf(
@ -40,8 +46,8 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
"IdOddzial" to data.studentClassId, "IdOddzial" to data.studentClassId,
"IdOkresKlasyfikacyjny" to data.studentSemesterId "IdOkresKlasyfikacyjny" to data.studentSemesterId
)) { json, _ -> )) { json, _ ->
val dates: MutableSet<Int> = mutableSetOf() val dates = mutableSetOf<Int>()
val lessons: MutableList<Lesson> = mutableListOf() val lessons = mutableListOf<Lesson>()
json.getJsonArray("Data")?.asJsonObjectList()?.forEach { lesson -> json.getJsonArray("Data")?.asJsonObjectList()?.forEach { lesson ->
if (lesson.getBoolean("PlanUcznia") != true) if (lesson.getBoolean("PlanUcznia") != true)
@ -166,7 +172,7 @@ class VulcanApiTimetable(override val data: DataVulcan, val onSuccess: () -> Uni
} }
} }
if (type != Lesson.TYPE_NORMAL) { if (type != Lesson.TYPE_NORMAL && lessonDate >= Date.getToday()) {
data.metadataList.add(Metadata( data.metadataList.add(Metadata(
profileId, profileId,
Metadata.TYPE_LESSON_CHANGE, Metadata.TYPE_LESSON_CHANGE,

View File

@ -38,10 +38,12 @@ class VulcanLoginApi(val data: DataVulcan, val onSuccess: () -> Unit) {
if (data.apiToken?.get(0) == 'F') VULCAN_API_PASSWORD_FAKELOG else VULCAN_API_PASSWORD, if (data.apiToken?.get(0) == 'F') VULCAN_API_PASSWORD_FAKELOG else VULCAN_API_PASSWORD,
data.apiCertificatePfx ?: "" data.apiCertificatePfx ?: ""
) )
onSuccess() data.loginStore.removeLoginData("certificatePfx")
return@run
} catch (e: Throwable) { } catch (e: Throwable) {
e.printStackTrace() e.printStackTrace()
} finally {
onSuccess()
return@run
} }
} }
if (data.symbol.isNotNullNorEmpty() && data.apiToken.isNotNullNorEmpty() && data.apiPin.isNotNullNorEmpty()) { if (data.symbol.isNotNullNorEmpty() && data.apiToken.isNotNullNorEmpty() && data.apiPin.isNotNullNorEmpty()) {

View File

@ -21,7 +21,10 @@ interface NotificationDao {
@Query("DELETE FROM notifications WHERE profileId = :profileId") @Query("DELETE FROM notifications WHERE profileId = :profileId")
fun clear(profileId: Int) fun clear(profileId: Int)
@Query("SELECT * FROM notifications") @Query("DELETE FROM notifications")
fun clearAll()
@Query("SELECT * FROM notifications ORDER BY addedDate DESC")
fun getAll(): LiveData<List<Notification>> fun getAll(): LiveData<List<Notification>>
@Query("SELECT * FROM notifications") @Query("SELECT * FROM notifications")

View File

@ -517,7 +517,7 @@ public class EventManualDialog {
registerEventManualDateLayout = dialogView.findViewById(R.id.registerEventManualDateLayout); registerEventManualDateLayout = dialogView.findViewById(R.id.registerEventManualDateLayout);
registerEventManualDate = dialogView.findViewById(R.id.registerEventManualDate); registerEventManualDate = dialogView.findViewById(R.id.registerEventManualDate);
registerEventManualDate.setCompoundDrawablesWithIntrinsicBounds(null, null, new IconicsDrawable(context, CommunityMaterial.Icon.cmd_calendar).size(IconicsSize.dp(16)).color(IconicsColor.colorInt(primaryTextColor)), null); registerEventManualDate.setCompoundDrawablesWithIntrinsicBounds(null, null, new IconicsDrawable(context, CommunityMaterial.Icon.cmd_calendar_outline).size(IconicsSize.dp(16)).color(IconicsColor.colorInt(primaryTextColor)), null);
//registerEventManualDate.setCompoundDrawablePadding(Utils.dpToPx(6)); //registerEventManualDate.setCompoundDrawablePadding(Utils.dpToPx(6));
registerEventManualLessonLayout = dialogView.findViewById(R.id.registerEventManualLessonLayout); registerEventManualLessonLayout = dialogView.findViewById(R.id.registerEventManualLessonLayout);
registerEventManualLesson = dialogView.findViewById(R.id.registerEventManualLesson); registerEventManualLesson = dialogView.findViewById(R.id.registerEventManualLesson);

View File

@ -6,6 +6,7 @@ package pl.szczodrzynski.edziennik.ui.dialogs.event
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter import android.graphics.PorterDuffColorFilter
import android.view.View
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer import androidx.lifecycle.Observer
@ -86,6 +87,7 @@ class EventManualV2Dialog(
defaultType?.let { defaultType?.let {
event.type = it event.type = it
}*/ }*/
b.shareSwitch.isChecked = event.sharedBy != null
} }
b.showMore.onClick { // TODO iconics is broken b.showMore.onClick { // TODO iconics is broken
@ -99,9 +101,32 @@ class EventManualV2Dialog(
} }
} }
updateShareText()
b.shareSwitch.onChange { _, isChecked ->
updateShareText(isChecked)
}
loadLists() loadLists()
}} }}
private fun updateShareText(checked: Boolean = b.shareSwitch.isChecked) {
val editingShared = editingEvent?.sharedBy != null
val editingOwn = editingEvent?.sharedBy == "self"
b.shareDetails.visibility = if (checked || editingShared)
View.VISIBLE
else View.GONE
val text = when {
checked && editingShared && editingOwn -> R.string.dialog_event_manual_share_will_change
checked && editingShared -> R.string.dialog_event_manual_share_will_request
!checked && editingShared -> R.string.dialog_event_manual_share_will_remove
else -> R.string.dialog_event_manual_share_first_notice
}
b.shareDetails.setText(text)
}
private fun loadLists() { launch { private fun loadLists() { launch {
val deferred = async(Dispatchers.Default) { val deferred = async(Dispatchers.Default) {
// get the team list // get the team list

View File

@ -6,15 +6,16 @@ import android.graphics.drawable.Drawable;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import com.applandeo.materialcalendarview.CalendarView; import com.applandeo.materialcalendarview.CalendarView;
import com.applandeo.materialcalendarview.EventDay; import com.applandeo.materialcalendarview.EventDay;
@ -27,6 +28,7 @@ import com.mikepenz.iconics.IconicsColor;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.IconicsSize; import com.mikepenz.iconics.IconicsSize;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial; import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
@ -34,13 +36,13 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsenceFull; import pl.szczodrzynski.edziennik.data.db.modules.teachers.TeacherAbsenceFull;
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaCalendarBinding; import pl.szczodrzynski.edziennik.databinding.FragmentAgendaCalendarBinding;
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaDefaultBinding; import pl.szczodrzynski.edziennik.databinding.FragmentAgendaDefaultBinding;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventListDialog; import pl.szczodrzynski.edziennik.ui.dialogs.event.EventListDialog;
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog; import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog;
import pl.szczodrzynski.edziennik.ui.dialogs.lessonchange.LessonChangeDialog; import pl.szczodrzynski.edziennik.ui.dialogs.lessonchange.LessonChangeDialog;
@ -51,11 +53,11 @@ import pl.szczodrzynski.edziennik.ui.modules.agenda.lessonchange.LessonChangeEve
import pl.szczodrzynski.edziennik.ui.modules.agenda.teacherabsence.TeacherAbsenceCounter; import pl.szczodrzynski.edziennik.ui.modules.agenda.teacherabsence.TeacherAbsenceCounter;
import pl.szczodrzynski.edziennik.ui.modules.agenda.teacherabsence.TeacherAbsenceEvent; import pl.szczodrzynski.edziennik.ui.modules.agenda.teacherabsence.TeacherAbsenceEvent;
import pl.szczodrzynski.edziennik.ui.modules.agenda.teacherabsence.TeacherAbsenceEventRenderer; import pl.szczodrzynski.edziennik.ui.modules.agenda.teacherabsence.TeacherAbsenceEventRenderer;
import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time;
import pl.szczodrzynski.edziennik.utils.Colors; import pl.szczodrzynski.edziennik.utils.Colors;
import pl.szczodrzynski.edziennik.utils.Themes; import pl.szczodrzynski.edziennik.utils.Themes;
import pl.szczodrzynski.edziennik.utils.Utils; import pl.szczodrzynski.edziennik.utils.Utils;
import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time;
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem; import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem;
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem; import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem;
@ -102,7 +104,7 @@ public class AgendaFragment extends Fragment {
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_add_event) .withTitle(R.string.menu_add_event)
.withDescription(R.string.menu_add_event_desc) .withDescription(R.string.menu_add_event_desc)
.withIcon(CommunityMaterial.Icon.cmd_calendar_plus) .withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
new MaterialDialog.Builder(activity) new MaterialDialog.Builder(activity)
@ -122,7 +124,7 @@ public class AgendaFragment extends Fragment {
}), }),
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_agenda_change_view) .withTitle(R.string.menu_agenda_change_view)
.withIcon(viewType == AGENDA_DEFAULT ? CommunityMaterial.Icon.cmd_calendar : CommunityMaterial.Icon2.cmd_view_list) .withIcon(viewType == AGENDA_DEFAULT ? CommunityMaterial.Icon.cmd_calendar_outline : CommunityMaterial.Icon.cmd_format_list_bulleted_square)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
viewType = viewType == AGENDA_DEFAULT ? AGENDA_CALENDAR : AGENDA_DEFAULT; viewType = viewType == AGENDA_DEFAULT ? AGENDA_CALENDAR : AGENDA_DEFAULT;
@ -133,7 +135,7 @@ public class AgendaFragment extends Fragment {
new BottomSheetSeparatorItem(true), new BottomSheetSeparatorItem(true),
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_EVENT, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_EVENT, true));

View File

@ -58,7 +58,7 @@ public class AnnouncementsFragment extends Fragment {
activity.getBottomSheet().prependItems( activity.getBottomSheet().prependItems(
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_ANNOUNCEMENT, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_ANNOUNCEMENT, true));

View File

@ -95,7 +95,7 @@ public class AttendanceFragment extends Fragment {
activity.getBottomSheet().prependItems( activity.getBottomSheet().prependItems(
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_ATTENDANCE, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_ATTENDANCE, true));
@ -133,7 +133,7 @@ public class AttendanceFragment extends Fragment {
CafeBar.builder(activity) CafeBar.builder(activity)
.to(activity.getNavView().getCoordinator()) .to(activity.getNavView().getCoordinator())
.content(R.string.sync_old_data_info) .content(R.string.sync_old_data_info)
.icon(new IconicsDrawable(activity).icon(CommunityMaterial.Icon2.cmd_sync).size(IconicsSize.dp(20)).color(IconicsColor.colorInt(Themes.INSTANCE.getPrimaryTextColor(activity)))) .icon(new IconicsDrawable(activity).icon(CommunityMaterial.Icon.cmd_download_outline).size(IconicsSize.dp(20)).color(IconicsColor.colorInt(Themes.INSTANCE.getPrimaryTextColor(activity))))
.positiveText(R.string.refresh) .positiveText(R.string.refresh)
.positiveColor(0xff4caf50) .positiveColor(0xff4caf50)
.negativeText(R.string.ok) .negativeText(R.string.ok)

View File

@ -69,7 +69,7 @@ public class BehaviourFragment extends Fragment {
activity.getBottomSheet().prependItems( activity.getBottomSheet().prependItems(
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_NOTICE, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_NOTICE, true));

View File

@ -9,21 +9,20 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView import android.widget.TextView
import com.mikepenz.iconics.IconicsDrawable
import androidx.cardview.widget.CardView import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
import com.mikepenz.iconics.utils.colorRes import com.mikepenz.iconics.utils.colorRes
import com.mikepenz.iconics.utils.sizeDp import com.mikepenz.iconics.utils.sizeDp
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_MOBIDZIENNIK
import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice
import pl.szczodrzynski.edziennik.data.db.modules.notices.NoticeFull import pl.szczodrzynski.edziennik.data.db.modules.notices.NoticeFull
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_MOBIDZIENNIK
import pl.szczodrzynski.edziennik.utils.Utils.bs import pl.szczodrzynski.edziennik.utils.Utils.bs
import pl.szczodrzynski.edziennik.utils.models.Date
class NoticesAdapter//getting the context and product list with constructor class NoticesAdapter//getting the context and product list with constructor
(private val context: Context, var noticeList: List<NoticeFull>) : RecyclerView.Adapter<NoticesAdapter.ViewHolder>() { (private val context: Context, var noticeList: List<NoticeFull>) : RecyclerView.Adapter<NoticesAdapter.ViewHolder>() {
@ -50,15 +49,15 @@ class NoticesAdapter//getting the context and product list with constructor
holder.noticesItemAddedDate.text = Date.fromMillis(notice.addedDate).formattedString holder.noticesItemAddedDate.text = Date.fromMillis(notice.addedDate).formattedString
if (notice.type == Notice.TYPE_POSITIVE) { if (notice.type == Notice.TYPE_POSITIVE) {
holder.noticesItemType.setImageDrawable(IconicsDrawable(context, CommunityMaterial.Icon2.cmd_plus_circle) holder.noticesItemType.setImageDrawable(IconicsDrawable(context, CommunityMaterial.Icon2.cmd_plus_circle_outline)
.colorRes(R.color.md_green_600) .colorRes(R.color.md_green_600)
.sizeDp(36)) .sizeDp(36))
} else if (notice.type == Notice.TYPE_NEGATIVE) { } else if (notice.type == Notice.TYPE_NEGATIVE) {
holder.noticesItemType.setImageDrawable(IconicsDrawable(context, CommunityMaterial.Icon.cmd_alert_decagram) holder.noticesItemType.setImageDrawable(IconicsDrawable(context, CommunityMaterial.Icon.cmd_alert_decagram_outline)
.colorRes(R.color.md_red_600) .colorRes(R.color.md_red_600)
.sizeDp(36)) .sizeDp(36))
} else { } else {
holder.noticesItemType.setImageDrawable(IconicsDrawable(context, CommunityMaterial.Icon2.cmd_message_outline) holder.noticesItemType.setImageDrawable(IconicsDrawable(context, SzkolnyFont.Icon.szf_message_processing_outline)
.colorRes(R.color.md_blue_500) .colorRes(R.color.md_blue_500)
.sizeDp(36)) .sizeDp(36))
} }

View File

@ -132,7 +132,7 @@ public class GradesFragment extends Fragment {
}), }),
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_grades_color_mode) .withTitle(R.string.menu_grades_color_mode)
.withIcon(CommunityMaterial.Icon2.cmd_palette) .withIcon(CommunityMaterial.Icon2.cmd_palette_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
new MaterialDialog.Builder(activity) new MaterialDialog.Builder(activity)
@ -195,7 +195,7 @@ public class GradesFragment extends Fragment {
new BottomSheetSeparatorItem(true), new BottomSheetSeparatorItem(true),
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_GRADE, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_GRADE, true));

View File

@ -1,11 +1,12 @@
package pl.szczodrzynski.edziennik.ui.modules.home; package pl.szczodrzynski.edziennik.ui.modules.home;
import androidx.databinding.DataBindingUtil;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.util.Log; import androidx.databinding.DataBindingUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -14,8 +15,8 @@ import java.util.TimerTask;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.databinding.ActivityCounterBinding;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
import pl.szczodrzynski.edziennik.databinding.ActivityCounterBinding;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time; import pl.szczodrzynski.edziennik.utils.models.Time;
@ -88,7 +89,7 @@ public class CounterActivity extends AppCompatActivity {
private void findLessons(Time syncedNow) { private void findLessons(Time syncedNow) {
AsyncTask.execute(() -> { AsyncTask.execute(() -> {
Date today = Date.getToday(); Date today = Date.getToday();
lessons = app.db.lessonDao().getAllNearestNow(App.profileId, today.clone().stepForward(0, 0, -today.getWeekDay()), today, syncedNow); lessons = app.db.lessonDao().getAllNearestNow(App.profileId, today.getWeekStart(), today, syncedNow);
if (lessons != null && lessons.size() != 0) { if (lessons != null && lessons.size() != 0) {
Date displayingDate = lessons.get(0).lessonDate; Date displayingDate = lessons.get(0).lessonDate;

View File

@ -37,6 +37,7 @@ import com.mikepenz.iconics.IconicsColor;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.IconicsSize; import com.mikepenz.iconics.IconicsSize;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial; import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -268,7 +269,7 @@ public class HomeFragment extends Fragment {
activity.getBottomSheet().prependItems( activity.getBottomSheet().prependItems(
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_set_student_number) .withTitle(R.string.menu_set_student_number)
.withIcon(CommunityMaterial.Icon.cmd_counter) .withIcon(SzkolnyFont.Icon.szf_clipboard_list_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
setNumberDialog(); setNumberDialog();
@ -276,7 +277,7 @@ public class HomeFragment extends Fragment {
new BottomSheetSeparatorItem(true), new BottomSheetSeparatorItem(true),
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_everything_as_read) .withTitle(R.string.menu_mark_everything_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, true));

View File

@ -0,0 +1,178 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-22
*/
package pl.szczodrzynski.edziennik.ui.modules.home
import android.content.Intent
import android.os.AsyncTask
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.databinding.DataBindingUtil
import com.afollestad.materialdialogs.DialogAction
import com.afollestad.materialdialogs.MaterialDialog
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
import pl.szczodrzynski.edziennik.data.db.modules.timetable.Lesson
import pl.szczodrzynski.edziennik.databinding.CardTimetableBinding
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment.updateInterval
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.models.Time
import java.util.*
class HomeTimetableCard(
private val app: App,
private val activity: MainActivity,
private val homeFragment: HomeFragment,
private val layoutInflater: LayoutInflater,
private val insertPoint: ViewGroup
) {
private lateinit var timetableTimer: Timer
private lateinit var b: CardTimetableBinding
private var bellSyncTime: Time? = null
private companion object {
const val TIME_TILL = 0
const val TIME_LEFT = 1
}
private var counterType = TIME_TILL
private val counterTarget = Time(0, 0, 0)
private val lessons = mutableListOf<Lesson>()
private val events = mutableListOf<Event>()
fun run() {
timetableTimer = Timer()
b = DataBindingUtil.inflate(layoutInflater, R.layout.card_timetable, null, false)
update()
insertPoint.addView(b.root, ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
b.cardTimetableFullscreenCounter.setOnClickListener {
activity.startActivity(Intent(activity, CounterActivity::class.java))
}
b.cardTimetableBellSync.setOnClickListener {
if (bellSyncTime == null) {
MaterialDialog.Builder(activity)
.title(R.string.bell_sync_title)
.content(R.string.bell_sync_cannot_now)
.positiveText(R.string.ok)
.show()
} else {
MaterialDialog.Builder(activity)
.title(R.string.bell_sync_title)
.content(app.getString(R.string.bell_sync_howto, bellSyncTime!!.stringHM).toString() +
when {
app.appConfig.bellSyncDiff != null -> app.getString(R.string.bell_sync_current_dialog,
(if (app.appConfig.bellSyncMultiplier == -1) "-" else "+") + app.appConfig.bellSyncDiff.stringHMS)
else -> ""
})
.positiveText(R.string.ok)
.negativeText(R.string.cancel)
.neutralText(R.string.reset)
.onPositive { _, _: DialogAction? ->
val bellDiff = Time.diff(Time.getNow(), bellSyncTime)
app.appConfig.bellSyncDiff = bellDiff
app.appConfig.bellSyncMultiplier = if (bellSyncTime!!.value > Time.getNow().value) -1 else 1
app.saveConfig("bellSyncDiff", "bellSyncMultiplier")
MaterialDialog.Builder(activity)
.title(R.string.bell_sync_title)
.content(app.getString(R.string.bell_sync_results, if (bellSyncTime!!.value > Time.getNow().value) "-" else "+", bellDiff.stringHMS))
.positiveText(R.string.ok)
.show()
}
.onNeutral { _, _ ->
MaterialDialog.Builder(activity)
.title(R.string.bell_sync_title)
.content(R.string.bell_sync_reset_confirm)
.positiveText(R.string.yes)
.negativeText(R.string.no)
.onPositive { _, _ ->
app.appConfig.bellSyncDiff = null
app.appConfig.bellSyncMultiplier = 0
app.saveConfig("bellSyncDiff", "bellSyncMultiplier")
}
.show()
}
.show()
}
}
HomeFragment.buttonAddDrawable(activity, b.cardTimetableButton, CommunityMaterial.Icon.cmd_arrow_right)
}
fun destroy() {
try {
timetableTimer.apply {
cancel()
purge()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun update() {
if (!homeFragment.isAdded) return
val now = Time.getNow()
val syncedNow: Time = when (app.appConfig.bellSyncDiff != null) {
true -> when {
app.appConfig.bellSyncMultiplier < 0 -> Time.sum(now, app.appConfig.bellSyncDiff)
app.appConfig.bellSyncMultiplier > 0 -> Time.diff(now, app.appConfig.bellSyncDiff)
else -> now
}
else -> now
}
if (lessons.size == 0 || syncedNow.value > counterTarget.value) {
findLessons(syncedNow)
} else {
scheduleUpdate(updateCounter(syncedNow))
}
}
private fun updateCounter(syncedNow: Time): Long {
val diff = Time.diff(counterTarget, syncedNow)
b.cardTimetableTimeLeft.text = when (counterType) {
TIME_TILL -> HomeFragment.timeTill(app, diff, app.appConfig.countInSeconds)
else -> HomeFragment.timeLeft(app, diff, app.appConfig.countInSeconds)
}
bellSyncTime = counterTarget.clone()
b.cardTimetableFullscreenCounter.visibility = View.VISIBLE
return updateInterval(app, diff)
}
private fun scheduleUpdate(newRefreshInterval: Long) {
timetableTimer.schedule(object : TimerTask() {
override fun run() {
activity.runOnUiThread { update() }
}
}, newRefreshInterval)
}
private fun findLessons(syncedNow: Time) {
AsyncTask.execute {
val today = Date.getToday()
val searchEnd = Date.getToday().stepForward(0, 0, -today.weekDay)
lessons.apply {
clear()
addAll(app.db.timetableDao().getBetweenDatesNow(today, searchEnd))
}
}
}
}

View File

@ -21,11 +21,11 @@ import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
import pl.szczodrzynski.edziennik.App; import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.MainActivity; import pl.szczodrzynski.edziennik.MainActivity;
import pl.szczodrzynski.edziennik.databinding.CardTimetableBinding; import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull; import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull; import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
import pl.szczodrzynski.edziennik.databinding.CardTimetableBinding;
import pl.szczodrzynski.edziennik.utils.models.Date; import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time; import pl.szczodrzynski.edziennik.utils.models.Time;
import pl.szczodrzynski.edziennik.utils.models.Week; import pl.szczodrzynski.edziennik.utils.models.Week;
@ -35,8 +35,8 @@ import static pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange.TY
import static pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment.updateInterval; import static pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment.updateInterval;
import static pl.szczodrzynski.edziennik.utils.Utils.bs; import static pl.szczodrzynski.edziennik.utils.Utils.bs;
public class HomeTimetableCard { public class HomeTimetableCardOld {
private static final String TAG = "HomeTimetableCard"; private static final String TAG = "HomeTimetableCardOld";
private App app; private App app;
private MainActivity a; private MainActivity a;
private HomeFragment f; private HomeFragment f;
@ -46,7 +46,7 @@ public class HomeTimetableCard {
private Timer timetableTimer; private Timer timetableTimer;
private Time bellSyncTime = null; private Time bellSyncTime = null;
public HomeTimetableCard(App app, MainActivity a, HomeFragment f, LayoutInflater layoutInflater, ViewGroup insertPoint) { public HomeTimetableCardOld(App app, MainActivity a, HomeFragment f, LayoutInflater layoutInflater, ViewGroup insertPoint) {
this.app = app; this.app = app;
this.a = a; this.a = a;
this.f = f; this.f = f;

View File

@ -9,6 +9,7 @@ import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
@ -52,7 +53,7 @@ class HomeworkFragment : Fragment() {
BottomSheetPrimaryItem(true) BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_add_event) .withTitle(R.string.menu_add_event)
.withDescription(R.string.menu_add_event_desc) .withDescription(R.string.menu_add_event_desc)
.withIcon(CommunityMaterial.Icon.cmd_calendar_plus) .withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
.withOnClickListener(View.OnClickListener { .withOnClickListener(View.OnClickListener {
activity.bottomSheet.close() activity.bottomSheet.close()
EventManualDialog(activity).show(app, null, null, null, EventManualDialog.DIALOG_HOMEWORK) EventManualDialog(activity).show(app, null, null, null, EventManualDialog.DIALOG_HOMEWORK)
@ -60,7 +61,7 @@ class HomeworkFragment : Fragment() {
BottomSheetSeparatorItem(true), BottomSheetSeparatorItem(true),
BottomSheetPrimaryItem(true) BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(View.OnClickListener { .withOnClickListener(View.OnClickListener {
activity.bottomSheet.close() activity.bottomSheet.close()
AsyncTask.execute { app.db.metadataDao().setAllSeen(App.profileId, Metadata.TYPE_HOMEWORK, true) } AsyncTask.execute { app.db.metadataDao().setAllSeen(App.profileId, Metadata.TYPE_HOMEWORK, true) }

View File

@ -104,7 +104,7 @@ public class LoginVulcanFragment extends Fragment {
b.helpButton.setOnClickListener((v) -> nav.navigate(R.id.loginVulcanHelpFragment, null, LoginActivity.navOptions)); b.helpButton.setOnClickListener((v) -> nav.navigate(R.id.loginVulcanHelpFragment, null, LoginActivity.navOptions));
b.backButton.setOnClickListener((v) -> nav.navigateUp()); b.backButton.setOnClickListener((v) -> nav.navigateUp());
b.loginQrScan.setImageDrawable(new IconicsDrawable(getActivity()).icon(CommunityMaterial.Icon2.cmd_qrcode).color(IconicsColor.colorInt(Color.BLACK)).size(IconicsSize.dp(72))); b.loginQrScan.setImageDrawable(new IconicsDrawable(getActivity()).icon(CommunityMaterial.Icon2.cmd_qrcode_scan).color(IconicsColor.colorInt(Color.BLACK)).size(IconicsSize.dp(72)));
b.loginQrScan.setOnClickListener((v -> { b.loginQrScan.setOnClickListener((v -> {
QrScannerActivity.resultHandler = result -> { QrScannerActivity.resultHandler = result -> {
try { try {

View File

@ -22,6 +22,7 @@ import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.iconics.IconicsSize import com.mikepenz.iconics.IconicsSize
import com.mikepenz.iconics.typeface.IIcon import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
import com.mikepenz.iconics.utils.sizeDp import com.mikepenz.iconics.utils.sizeDp
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
@ -224,17 +225,18 @@ class MessageFragment : Fragment(), CoroutineScope {
attachmentChip.ellipsize = TextUtils.TruncateAt.MIDDLE attachmentChip.ellipsize = TextUtils.TruncateAt.MIDDLE
// create an icon for the attachment // create an icon for the attachment
var icon: IIcon = CommunityMaterial.Icon.cmd_file var icon: IIcon = CommunityMaterial.Icon.cmd_file_outline
when (Utils.getExtensionFromFileName(name)) { when (Utils.getExtensionFromFileName(name)) {
"txt" -> icon = CommunityMaterial.Icon.cmd_file_document "txt" -> icon = CommunityMaterial.Icon.cmd_file_document_outline
"doc", "docx", "odt", "rtf" -> icon = CommunityMaterial.Icon.cmd_file_word "doc", "docx", "odt", "rtf" -> icon = SzkolnyFont.Icon.szf_file_word_outline
"xls", "xlsx", "ods" -> icon = CommunityMaterial.Icon.cmd_file_excel "xls", "xlsx", "ods" -> icon = SzkolnyFont.Icon.szf_file_excel_outline
"ppt", "pptx", "odp" -> icon = CommunityMaterial.Icon.cmd_file_powerpoint "ppt", "pptx", "odp" -> icon = SzkolnyFont.Icon.szf_file_powerpoint_outline
"pdf" -> icon = CommunityMaterial.Icon.cmd_file_pdf "pdf" -> icon = SzkolnyFont.Icon.szf_file_pdf_outline
"mp3", "wav", "aac" -> icon = CommunityMaterial.Icon.cmd_file_music "mp3", "wav", "aac" -> icon = SzkolnyFont.Icon.szf_file_music_outline
"mp4", "avi", "3gp", "mkv", "flv" -> icon = CommunityMaterial.Icon.cmd_file_video "mp4", "avi", "3gp", "mkv", "flv" -> icon = SzkolnyFont.Icon.szf_file_video_outline
"jpg", "jpeg", "png", "bmp", "gif" -> icon = CommunityMaterial.Icon.cmd_file_image "jpg", "jpeg", "png", "bmp", "gif" -> icon = SzkolnyFont.Icon.szf_file_image_outline
"zip", "rar", "tar", "7z" -> icon = CommunityMaterial.Icon.cmd_file_lock "zip", "rar", "tar", "7z" -> icon = SzkolnyFont.Icon.szf_zip_box_outline
"html", "cpp", "c", "h", "css", "java", "py" -> icon = SzkolnyFont.Icon.szf_file_code_outline
} }
attachmentChip.chipIcon = IconicsDrawable(activity).color(IconicsColor.colorRes(R.color.colorPrimary)).icon(icon).size(IconicsSize.dp(26)) attachmentChip.chipIcon = IconicsDrawable(activity).color(IconicsColor.colorRes(R.color.colorPrimary)).icon(icon).size(IconicsSize.dp(26))
attachmentChip.closeIcon = IconicsDrawable(activity).icon(CommunityMaterial.Icon.cmd_check).size(IconicsSize.dp(18)).color(IconicsColor.colorInt(Utils.getAttr(activity, android.R.attr.textColorPrimary))) attachmentChip.closeIcon = IconicsDrawable(activity).icon(CommunityMaterial.Icon.cmd_check).size(IconicsSize.dp(18)).color(IconicsColor.colorInt(Utils.getAttr(activity, android.R.attr.textColorPrimary)))

View File

@ -1,104 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.notifications;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Notification;
import static pl.szczodrzynski.edziennik.utils.Utils.d;
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.ViewHolder> {
private static final String TAG = "NotificationsAdapter";
private Context context;
private List<Notification> notificationList;
//getting the context and product list with constructor
public NotificationsAdapter(Context mCtx, List<Notification> notificationList) {
this.context = mCtx;
this.notificationList = notificationList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.row_notifications_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
App app = (App) context.getApplicationContext();
Notification notification = notificationList.get(position);
holder.notificationsItemDate.setText(Date.fromMillis(notification.addedDate).getFormattedString());
holder.notificationsItemText.setText(notification.text);
holder.notificationsItemTitle.setText(notification.title);
holder.notificationsItemType.setText(Notification.stringType(context, notification.type));
holder.notificationsItemCard.setOnClickListener((v -> {
Intent intent = new Intent("android.intent.action.MAIN");
notification.fillIntent(intent);
d(TAG, "notification with item "+notification.redirectFragmentId+" extras "+(intent.getExtras() == null ? "null" : intent.getExtras().toString()));
//Log.d(TAG, "Got date "+intent.getLongExtra("timetableDate", 0));
if (notification.profileId != -1 && notification.profileId != app.profile.getId() && context instanceof Activity) {
Toast.makeText(app, app.getString(R.string.toast_changing_profile), Toast.LENGTH_LONG).show();
}
app.sendBroadcast(intent);
}));
if (!notification.seen) {
holder.notificationsItemText.setBackground(context.getResources().getDrawable(R.drawable.bg_rounded_8dp));
holder.notificationsItemText.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
}
else {
holder.notificationsItemText.setBackground(null);
}
}
@Override
public int getItemCount() {
return notificationList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
CardView notificationsItemCard;
TextView notificationsItemDate;
TextView notificationsItemText;
TextView notificationsItemTitle;
TextView notificationsItemType;
ViewHolder(View itemView) {
super(itemView);
notificationsItemCard = itemView.findViewById(R.id.notificationsItemCard);
notificationsItemDate = itemView.findViewById(R.id.notificationsItemDate);
notificationsItemText = itemView.findViewById(R.id.notificationsItemText);
notificationsItemTitle = itemView.findViewById(R.id.notificationsItemTitle);
notificationsItemType = itemView.findViewById(R.id.notificationsItemType);
}
}
}

View File

@ -0,0 +1,72 @@
package pl.szczodrzynski.edziennik.ui.modules.notifications
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.*
import pl.szczodrzynski.edziennik.data.db.modules.notification.Notification
import pl.szczodrzynski.edziennik.data.db.modules.notification.getNotificationTitle
import pl.szczodrzynski.edziennik.utils.Utils.d
import pl.szczodrzynski.edziennik.utils.models.Date
class NotificationsAdapter(
private val context: Context
) : RecyclerView.Adapter<NotificationsAdapter.ViewHolder>() {
companion object {
private const val TAG = "NotificationsAdapter"
}
var items = listOf<Notification>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.row_notifications_item, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val app = context.applicationContext as App
val notification = items[position]
val date = Date.fromMillis(notification.addedDate).formattedString
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(context)
holder.title.text = notification.text
holder.profileDate.text = listOf(
notification.profileName ?: "",
"",
date.asColoredSpannable(colorSecondary)
).concat()
holder.type.text = context.getNotificationTitle(notification.type)
holder.root.onClick {
val intent = Intent("android.intent.action.MAIN")
notification.fillIntent(intent)
d(TAG, "notification with item " + notification.viewId + " extras " + if (intent.extras == null) "null" else intent.extras!!.toString())
//Log.d(TAG, "Got date "+intent.getLongExtra("timetableDate", 0));
if (notification.profileId != -1 && notification.profileId != app.profile.id && context is Activity) {
Toast.makeText(app, app.getString(R.string.toast_changing_profile), Toast.LENGTH_LONG).show()
}
app.sendBroadcast(intent)
}
}
override fun getItemCount() = items.size
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var root = itemView
var title: TextView = itemView.findViewById(R.id.title)
var profileDate: TextView = itemView.findViewById(R.id.profileDate)
var type: TextView = itemView.findViewById(R.id.type)
}
}

View File

@ -1,65 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.notifications;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.databinding.FragmentNotificationsBinding;
import pl.szczodrzynski.edziennik.utils.Themes;
public class NotificationsFragment extends Fragment {
private App app = null;
private Activity activity = null;
private FragmentNotificationsBinding b = null;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
activity = getActivity();
if (getActivity() == null || getContext() == null)
return null;
app = (App) activity.getApplication();
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false);
// activity, context and profile is valid
b = DataBindingUtil.inflate(inflater, R.layout.fragment_notifications, container, false);
return b.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
return;
RecyclerView recyclerView = b.notificationsView;
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
if (app.appConfig.notifications.size() > 0) {
NotificationsAdapter adapter = new NotificationsAdapter(getContext(), app.appConfig.notifications);
recyclerView.setAdapter(adapter);
recyclerView.setVisibility(View.VISIBLE);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
//linearLayoutManager.setReverseLayout(true);
//linearLayoutManager.setStackFromEnd(true);
recyclerView.setLayoutManager(linearLayoutManager);
b.notificationsNoData.setVisibility(View.GONE);
}
else {
recyclerView.setVisibility(View.GONE);
b.notificationsNoData.setVisibility(View.VISIBLE);
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-11-22.
*/
package pl.szczodrzynski.edziennik.ui.modules.notifications
import android.os.AsyncTask
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DividerItemDecoration.HORIZONTAL
import androidx.recyclerview.widget.LinearLayoutManager
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.FragmentNotificationsBinding
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
class NotificationsFragment : Fragment() {
private lateinit var app: App
private lateinit var activity: MainActivity
private lateinit var b: FragmentNotificationsBinding
private val adapter by lazy {
NotificationsAdapter(activity)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
if (context == null)
return null
app = activity.application as App
context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid
b = FragmentNotificationsBinding.inflate(inflater)
return b.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// TODO check if app, activity, b can be null
if (app.profile == null || !isAdded)
return
activity.bottomSheet.prependItems(
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_remove_notifications)
.withIcon(CommunityMaterial.Icon.cmd_delete_sweep_outline)
.withOnClickListener(View.OnClickListener {
activity.bottomSheet.close()
AsyncTask.execute { app.db.notificationDao().clearAll() }
Toast.makeText(activity, R.string.menu_remove_notifications_success, Toast.LENGTH_SHORT).show()
}))
app.db.notificationDao()
.getAll()
.observe(this, Observer { notifications ->
if (app.profile == null || !isAdded) return@Observer
adapter.items = notifications
if (b.notificationsView.adapter == null) {
b.notificationsView.adapter = adapter
b.notificationsView.apply {
setHasFixedSize(true)
layoutManager = LinearLayoutManager(context).apply {
addItemDecoration(SimpleDividerItemDecoration(context))
}
}
}
adapter.notifyDataSetChanged()
if (notifications != null && notifications.isNotEmpty()) {
b.notificationsView.visibility = View.VISIBLE
b.notificationsNoData.visibility = View.GONE
} else {
b.notificationsView.visibility = View.GONE
b.notificationsNoData.visibility = View.VISIBLE
}
})
}
}

View File

@ -39,7 +39,7 @@ class SettingsLicenseActivity : MaterialAboutActivity() {
libraryUrl: String): MaterialAboutCard { libraryUrl: String): MaterialAboutCard {
val licenseItem = MaterialAboutActionItem.Builder() val licenseItem = MaterialAboutActionItem.Builder()
.icon(IconicsDrawable(this) .icon(IconicsDrawable(this)
.icon(CommunityMaterial.Icon.cmd_book) .icon(CommunityMaterial.Icon.cmd_book_outline)
.colorInt(foregroundColor) .colorInt(foregroundColor)
.sizeDp(18)) .sizeDp(18))
.setIconGravity(MaterialAboutActionItem.GRAVITY_TOP) .setIconGravity(MaterialAboutActionItem.GRAVITY_TOP)

View File

@ -29,6 +29,7 @@ import com.mikepenz.iconics.IconicsColor;
import com.mikepenz.iconics.IconicsDrawable; import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.IconicsSize; import com.mikepenz.iconics.IconicsSize;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial; import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
import com.theartofdev.edmodo.cropper.CropImage; import com.theartofdev.edmodo.cropper.CropImage;
import com.theartofdev.edmodo.cropper.CropImageView; import com.theartofdev.edmodo.cropper.CropImageView;
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog; import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
@ -259,7 +260,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_profile_remove_text), getString(R.string.settings_profile_remove_text),
getString(R.string.settings_profile_remove_subtext), getString(R.string.settings_profile_remove_subtext),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_delete_empty) .icon(SzkolnyFont.Icon.szf_delete_empty_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -287,7 +288,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_theme_theme_text), getString(R.string.settings_theme_theme_text),
Themes.INSTANCE.getThemeName(activity), Themes.INSTANCE.getThemeName(activity),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_palette) .icon(CommunityMaterial.Icon2.cmd_palette_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -313,7 +314,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_theme_mini_drawer_text), getString(R.string.settings_theme_mini_drawer_text),
getString(R.string.settings_theme_mini_drawer_subtext), getString(R.string.settings_theme_mini_drawer_subtext),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_chevron_left) .icon(CommunityMaterial.Icon.cmd_dots_vertical)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -339,7 +340,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_theme_mini_drawer_buttons_text), getString(R.string.settings_theme_mini_drawer_buttons_text),
null, null,
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_menu) .icon(CommunityMaterial.Icon.cmd_format_list_checks)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -403,7 +404,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_theme_drawer_header_text), getString(R.string.settings_theme_drawer_header_text),
null, null,
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_image) .icon(CommunityMaterial.Icon2.cmd_image_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -504,7 +505,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_sync_wifi_text), getString(R.string.settings_sync_wifi_text),
getString(R.string.settings_sync_wifi_subtext), getString(R.string.settings_sync_wifi_subtext),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_wifi_strength_4) .icon(CommunityMaterial.Icon2.cmd_wifi_strength_2)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -526,7 +527,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_sync_sync_interval_text), getString(R.string.settings_sync_sync_interval_text),
getString(R.string.settings_sync_sync_interval_subtext_disabled), getString(R.string.settings_sync_sync_interval_subtext_disabled),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_sync) .icon(CommunityMaterial.Icon.cmd_download_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
); );
@ -619,7 +620,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_sync_quiet_hours_text), getString(R.string.settings_sync_quiet_hours_text),
getString(R.string.settings_sync_quiet_hours_subtext_disabled), getString(R.string.settings_sync_quiet_hours_subtext_disabled),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_bell_sleep) .icon(CommunityMaterial.Icon.cmd_bell_sleep_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
); );
@ -740,7 +741,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_sync_notifications_settings_text), getString(R.string.settings_sync_notifications_settings_text),
getString(R.string.settings_sync_notifications_settings_subtext), getString(R.string.settings_sync_notifications_settings_subtext),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_settings) .icon(CommunityMaterial.Icon2.cmd_settings_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -820,7 +821,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_register_shared_events_text), getString(R.string.settings_register_shared_events_text),
getString(R.string.settings_register_shared_events_subtext), getString(R.string.settings_register_shared_events_subtext),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_share_variant) .icon(CommunityMaterial.Icon2.cmd_share_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -888,7 +889,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_register_allow_registration_text), getString(R.string.settings_register_allow_registration_text),
getString(R.string.settings_register_allow_registration_subtext), getString(R.string.settings_register_allow_registration_subtext),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_account_circle) .icon(CommunityMaterial.Icon.cmd_account_circle_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
); );
@ -958,7 +959,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_register_bell_sync_text), getString(R.string.settings_register_bell_sync_text),
getRegisterCardBellSyncSubText(), getRegisterCardBellSyncSubText(),
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_alarm_bell) .icon(SzkolnyFont.Icon.szf_alarm_bell_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
); );
@ -1030,7 +1031,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_register_dont_count_zero_text), getString(R.string.settings_register_dont_count_zero_text),
null, null,
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_numeric_0_box) .icon(CommunityMaterial.Icon2.cmd_numeric_0_box_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -1065,7 +1066,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
getString(R.string.settings_register_show_teacher_absences_text), getString(R.string.settings_register_show_teacher_absences_text),
null, null,
new IconicsDrawable(activity) new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_account_arrow_right) .icon(CommunityMaterial.Icon.cmd_account_arrow_right_outline)
.size(IconicsSize.dp(iconSizeDp)) .size(IconicsSize.dp(iconSizeDp))
.color(IconicsColor.colorInt(iconColor)) .color(IconicsColor.colorInt(iconColor))
) )
@ -1109,7 +1110,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.subTextColor(secondaryTextOnPrimaryBg) .subTextColor(secondaryTextOnPrimaryBg)
.subText(BuildConfig.VERSION_NAME + ", " + BuildConfig.BUILD_TYPE) .subText(BuildConfig.VERSION_NAME + ", " + BuildConfig.BUILD_TYPE)
.icon(new IconicsDrawable(activity) .icon(new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_information) .icon(CommunityMaterial.Icon2.cmd_information_outline)
.color(IconicsColor.colorInt(primaryTextOnPrimaryBg)) .color(IconicsColor.colorInt(primaryTextOnPrimaryBg))
.size(IconicsSize.dp(iconSizeDp))) .size(IconicsSize.dp(iconSizeDp)))
.build(); .build();
@ -1133,7 +1134,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.textColor(primaryTextOnPrimaryBg) .textColor(primaryTextOnPrimaryBg)
.subTextColor(secondaryTextOnPrimaryBg) .subTextColor(secondaryTextOnPrimaryBg)
.icon(new IconicsDrawable(activity) .icon(new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon2.cmd_shield_half_full) .icon(CommunityMaterial.Icon2.cmd_shield_outline)
.color(IconicsColor.colorInt(primaryTextOnPrimaryBg)) .color(IconicsColor.colorInt(primaryTextOnPrimaryBg))
.size(IconicsSize.dp(iconSizeDp))) .size(IconicsSize.dp(iconSizeDp)))
.setOnClickAction(ConvenienceBuilder.createWebsiteOnClickAction(activity, Uri.parse("https://szkolny.eu/privacy-policy"))) .setOnClickAction(ConvenienceBuilder.createWebsiteOnClickAction(activity, Uri.parse("https://szkolny.eu/privacy-policy")))
@ -1145,7 +1146,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.subTextColor(secondaryTextOnPrimaryBg) .subTextColor(secondaryTextOnPrimaryBg)
.subText(R.string.settings_about_discord_subtext) .subText(R.string.settings_about_discord_subtext)
.icon(new IconicsDrawable(activity) .icon(new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_discord) .icon(SzkolnyFont.Icon.szf_discord_outline)
.color(IconicsColor.colorInt(primaryTextOnPrimaryBg)) .color(IconicsColor.colorInt(primaryTextOnPrimaryBg))
.size(IconicsSize.dp(iconSizeDp))) .size(IconicsSize.dp(iconSizeDp)))
.setOnClickAction(ConvenienceBuilder.createWebsiteOnClickAction(activity, Uri.parse("https://discord.gg/n9e8pWr"))) .setOnClickAction(ConvenienceBuilder.createWebsiteOnClickAction(activity, Uri.parse("https://discord.gg/n9e8pWr")))
@ -1270,7 +1271,7 @@ public class SettingsNewFragment extends MaterialAboutFragment {
.textColor(primaryTextOnPrimaryBg) .textColor(primaryTextOnPrimaryBg)
.subTextColor(secondaryTextOnPrimaryBg) .subTextColor(secondaryTextOnPrimaryBg)
.icon(new IconicsDrawable(activity) .icon(new IconicsDrawable(activity)
.icon(CommunityMaterial.Icon.cmd_bug) .icon(CommunityMaterial.Icon.cmd_bug_outline)
.color(IconicsColor.colorInt(primaryTextOnPrimaryBg)) .color(IconicsColor.colorInt(primaryTextOnPrimaryBg))
.size(IconicsSize.dp(iconSizeDp))) .size(IconicsSize.dp(iconSizeDp)))
.setOnClickAction(() -> { .setOnClickAction(() -> {

View File

@ -37,6 +37,7 @@ import androidx.viewpager.widget.ViewPager;
import com.afollestad.materialdialogs.MaterialDialog; import com.afollestad.materialdialogs.MaterialDialog;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial; import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial;
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
@ -103,7 +104,7 @@ public class TimetableFragment extends Fragment {
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_add_event) .withTitle(R.string.menu_add_event)
.withDescription(R.string.menu_add_event_desc) .withDescription(R.string.menu_add_event_desc)
.withIcon(CommunityMaterial.Icon.cmd_calendar_plus) .withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
new MaterialDialog.Builder(activity) new MaterialDialog.Builder(activity)
@ -132,7 +133,7 @@ public class TimetableFragment extends Fragment {
new BottomSheetSeparatorItem(true), new BottomSheetSeparatorItem(true),
new BottomSheetPrimaryItem(true) new BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read) .withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check) .withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(v3 -> { .withOnClickListener(v3 -> {
activity.getBottomSheet().close(); activity.getBottomSheet().close();
AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_LESSON_CHANGE, true)); AsyncTask.execute(() -> app.db.metadataDao().setAllSeen(App.profileId, TYPE_LESSON_CHANGE, true));
@ -183,7 +184,7 @@ public class TimetableFragment extends Fragment {
if (app == null || app.profile == null || activity == null || b == null || !isAdded()) if (app == null || app.profile == null || activity == null || b == null || !isAdded())
return; return;
List<LessonFull> lessons = app.db.lessonDao().getAllWeekNow(App.profileId, today.clone().stepForward(0, 0, -today.getWeekDay()), today); List<LessonFull> lessons = app.db.lessonDao().getAllWeekNow(App.profileId, today.getWeekStart(), today);
displayingDate = HomeFragment.findDateWithLessons(App.profileId, lessons); displayingDate = HomeFragment.findDateWithLessons(App.profileId, lessons);
pageSelection = app.appConfig.timetableDisplayDaysBackward + Date.diffDays(displayingDate, today); // DEFAULT HERE pageSelection = app.appConfig.timetableDisplayDaysBackward + Date.diffDays(displayingDate, today); // DEFAULT HERE

View File

@ -4,21 +4,28 @@ import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.google.android.material.datepicker.MaterialDatePicker
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import com.mikepenz.iconics.typeface.library.szkolny.font.SzkolnyFont
import kotlinx.coroutines.* import kotlinx.coroutines.*
import pl.szczodrzynski.edziennik.App import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.LOGIN_TYPE_LIBRUS import pl.szczodrzynski.edziennik.api.v2.LOGIN_TYPE_LIBRUS
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding import pl.szczodrzynski.edziennik.databinding.FragmentTimetableV2Binding
import pl.szczodrzynski.edziennik.utils.Themes import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.edziennik.utils.models.Date import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
class TimetableFragment : Fragment(), CoroutineScope { class TimetableFragment : Fragment(), CoroutineScope {
@ -151,11 +158,40 @@ class TimetableFragment : Fragment(), CoroutineScope {
b.tabLayout.setUpWithViewPager(b.viewPager) b.tabLayout.setUpWithViewPager(b.viewPager)
b.tabLayout.setCurrentItem(items.indexOfFirst { it.value == today }, false) b.tabLayout.setCurrentItem(items.indexOfFirst { it.value == today }, false)
activity.navView.bottomSheet.prependItems(
BottomSheetPrimaryItem(true)
.withTitle(R.string.timetable_select_day)
.withIcon(SzkolnyFont.Icon.szf_calendar_today_outline)
.withOnClickListener(View.OnClickListener {
activity.bottomSheet.close()
MaterialDatePicker.Builder
.datePicker()
.setSelection(Date.getToday().inMillis)
.build()
.apply {
addOnPositiveButtonClickListener { dateInMillis ->
val dateSelected = Date.fromMillis(dateInMillis)
b.tabLayout.setCurrentItem(items.indexOfFirst { it == dateSelected }, true)
}
show(this@TimetableFragment.activity.supportFragmentManager, "MaterialDatePicker")
}
}),
BottomSheetSeparatorItem(true),
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
.withOnClickListener(View.OnClickListener {
activity.bottomSheet.close()
AsyncTask.execute { app.db.metadataDao().setAllSeen(App.profileId, Metadata.TYPE_LESSON_CHANGE, true) }
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
})
)
//activity.navView.bottomBar.fabEnable = true //activity.navView.bottomBar.fabEnable = true
activity.navView.bottomBar.fabExtendedText = getString(R.string.timetable_today) activity.navView.bottomBar.fabExtendedText = getString(R.string.timetable_today)
activity.navView.bottomBar.fabIcon = CommunityMaterial.Icon.cmd_calendar_today activity.navView.bottomBar.fabIcon = SzkolnyFont.Icon.szf_calendar_today_outline
activity.navView.setFabOnClickListener(View.OnClickListener { activity.navView.setFabOnClickListener(View.OnClickListener {
b.tabLayout.setCurrentItem(items.indexOfFirst { it.value == today }, true) b.tabLayout.setCurrentItem(items.indexOfFirst { it.value == today }, true)
}) })
}} }}
} }

View File

@ -19,7 +19,7 @@ class TimetablePagerAdapter(
} }
private val today by lazy { Date.getToday() } private val today by lazy { Date.getToday() }
private val weekStart by lazy { today.clone().stepForward(0, 0, -today.weekDay) } private val weekStart by lazy { today.weekStart }
private val weekEnd by lazy { weekStart.clone().stepForward(0, 0, 6) } private val weekEnd by lazy { weekStart.clone().stepForward(0, 0, 6) }
override fun getItem(position: Int): Fragment { override fun getItem(position: Int): Fragment {
@ -49,4 +49,4 @@ class TimetablePagerAdapter(
} }
return pageTitle return pageTitle
} }
} }

View File

@ -120,7 +120,7 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
parent?.removeAllViews() parent?.removeAllViews()
parent?.addView(view) parent?.addView(view)
val b = TimetableNoTimetableBinding.bind(view) val b = TimetableNoTimetableBinding.bind(view)
val weekStart = date.clone().stepForward(0, 0, -date.weekDay).stringY_m_d val weekStart = date.weekStart.stringY_m_d
b.noTimetableSync.onClick { b.noTimetableSync.onClick {
it.isEnabled = false it.isEnabled = false
EdziennikTask.syncProfile( EdziennikTask.syncProfile(
@ -247,6 +247,8 @@ class TimetableDayFragment : Fragment(), CoroutineScope {
lb.detailsFirst.text = listOfNotEmpty(timeRange, classroomInfo).concat(bullet) lb.detailsFirst.text = listOfNotEmpty(timeRange, classroomInfo).concat(bullet)
lb.detailsSecond.text = listOfNotEmpty(teacherInfo, teamInfo).concat(bullet) lb.detailsSecond.text = listOfNotEmpty(teacherInfo, teamInfo).concat(bullet)
lb.unread = lesson.type != Lesson.TYPE_NORMAL && !lesson.seen
//lb.subjectName.typeface = Typeface.create("sans-serif-light", Typeface.BOLD) //lb.subjectName.typeface = Typeface.create("sans-serif-light", Typeface.BOLD)
when (lesson.type) { when (lesson.type) {
Lesson.TYPE_NORMAL -> { Lesson.TYPE_NORMAL -> {

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-11-22.
*/
package pl.szczodrzynski.edziennik.utils;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
import pl.szczodrzynski.edziennik.R;
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
private Drawable mDivider;
public SimpleDividerItemDecoration(Context context) {
mDivider = context.getResources().getDrawable(R.drawable.divider);
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();
int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) Kuba Szczodrzyński 2019-11-22.
*/
package pl.szczodrzynski.edziennik.utils
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.KeyEvent
import android.view.KeyEvent.KEYCODE_BACK
import androidx.annotation.NonNull
import com.google.android.material.textfield.TextInputEditText
class TextInputKeyboardEdit : TextInputEditText {
/**
* Keyboard Listener
*/
internal var listener: KeyboardListener? = null
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
super.onFocusChanged(focused, direction, previouslyFocusedRect)
if (listener != null)
listener!!.onStateChanged(this, true)
}
override fun onKeyPreIme(keyCode: Int, @NonNull event: KeyEvent): Boolean {
if (event.keyCode == KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
if (listener != null)
listener!!.onStateChanged(this, false)
// Hide cursor
isFocusable = false
// Set EditText to be focusable again
isFocusable = true
isFocusableInTouchMode = true
}
return super.onKeyPreIme(keyCode, event)
}
fun setOnKeyboardListener(listener: KeyboardListener) {
this.listener = listener
}
interface KeyboardListener {
fun onStateChanged(keyboardEditText: TextInputKeyboardEdit, showing: Boolean)
}
}

View File

@ -41,6 +41,10 @@ public class Date implements Comparable<Date> {
return new Date(this.year, this.month, this.day); return new Date(this.year, this.month, this.day);
} }
public Date getWeekStart() {
return clone().stepForward(0, 0, -getWeekDay());
}
public static Date fromYmd(String dateTime) { public static Date fromYmd(String dateTime) {
return new Date(Integer.parseInt(dateTime.substring(0, 4)), Integer.parseInt(dateTime.substring(4, 6)), Integer.parseInt(dateTime.substring(6, 8))); return new Date(Integer.parseInt(dateTime.substring(0, 4)), Integer.parseInt(dateTime.substring(4, 6)), Integer.parseInt(dateTime.substring(6, 8)));
} }
@ -134,11 +138,23 @@ public class Date implements Comparable<Date> {
public Date stepForward(int years, int months, int days) { public Date stepForward(int years, int months, int days) {
this.day += days; this.day += days;
if (day <= 0) {
month--;
if(month <= 0) {
month += 12;
year--;
}
day += daysInMonth();
}
if (day > daysInMonth()) { if (day > daysInMonth()) {
day -= daysInMonth(); day -= daysInMonth();
month++; month++;
} }
this.month += months; this.month += months;
if(month <= 0) {
month += 12;
year--;
}
if (month > 12) { if (month > 12) {
month -= 12; month -= 12;
year++; year++;
@ -176,6 +192,7 @@ public class Date implements Comparable<Date> {
public boolean isLeap() { public boolean isLeap() {
return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0); return ((year & 3) == 0) && ((year % 100) != 0 || (year % 400) == 0);
} }
public int daysInMonth() { public int daysInMonth() {
switch (month) { switch (month) {
case 1: case 1:

View File

@ -117,7 +117,7 @@ public class WidgetNotifications extends AppWidgetProvider {
.color(IconicsColor.colorInt(Color.WHITE)) .color(IconicsColor.colorInt(Color.WHITE))
.size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap()); .size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap());
views.setImageViewBitmap(R.id.widgetNotificationsSync, new IconicsDrawable(context, CommunityMaterial.Icon2.cmd_sync) views.setImageViewBitmap(R.id.widgetNotificationsSync, new IconicsDrawable(context, CommunityMaterial.Icon.cmd_download_outline)
.color(IconicsColor.colorInt(Color.WHITE)) .color(IconicsColor.colorInt(Color.WHITE))
.size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap()); .size(IconicsSize.dp(widgetConfig.bigStyle ? 24 : 16)).toBitmap());

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Kuba Szczodrzyński 2019-11-22.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="1dp"
android:height="1dp" />
<solid android:color="@color/dividerColor" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,37 @@
<!--
~ Copyright (c) Kuba Szczodrzyński 2019-11-22.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="128dp"
android:height="128dp"
android:viewportWidth="128"
android:viewportHeight="128">
<path
android:pathData="m104,18h-80c-5.523,0 -10,4.477 -10,10v84.699c0,2.93 2.371,5.301 5.301,5.301h0.012c1.691,0 3.277,-0.805 4.277,-2.164l10.082,-13.75c1.883,-2.566 4.875,-4.086 8.063,-4.086h62.266c5.523,0 10,-4.477 10,-10v-60c0,-5.523 -4.477,-10 -10,-10z"
android:fillColor="#2babee"/>
<path
android:pathData="m128,104c0,13.254 -10.746,24 -24,24 -13.254,0 -24,-10.746 -24,-24s10.746,-24 24,-24c13.254,0 24,10.746 24,24z"
android:fillColor="#fc556c"/>
<path
android:pathData="m114.84,98.824 l-16.012,16.012c-1.555,1.555 -4.102,1.555 -5.656,0 -1.555,-1.559 -1.555,-4.106 0,-5.656l16.012,-16.012c1.555,-1.555 4.102,-1.555 5.656,0 1.551,1.555 1.551,4.102 0,5.656z"
android:fillColor="#fff"/>
<path
android:pathData="m93.164,98.824 l16.012,16.012c1.555,1.555 4.102,1.555 5.656,0 1.555,-1.559 1.555,-4.106 0,-5.656l-16.012,-16.012c-1.555,-1.555 -4.102,-1.555 -5.656,0 -1.551,1.555 -1.551,4.102 0,5.656z"
android:fillColor="#fff"/>
<path
android:pathData="m74,78h-36c-2.211,0 -4,-1.789 -4,-4 0,-2.211 1.789,-4 4,-4h36c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4z"
android:fillColor="#f1fcff"/>
<path
android:pathData="m72,54h18c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4h-18c-2.211,0 -4,-1.789 -4,-4 0,-2.211 1.789,-4 4,-4z"
android:fillColor="#f1fcff"/>
<path
android:pathData="m38,54h20c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4h-20c-2.211,0 -4,-1.789 -4,-4 0,-2.211 1.789,-4 4,-4z"
android:fillColor="#f1fcff"/>
<path
android:pathData="m38,38h34c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4h-34c-2.211,0 -4,-1.789 -4,-4 0,-2.211 1.789,-4 4,-4z"
android:fillColor="#f1fcff"/>
<path
android:pathData="m86,38h4c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4h-4c-2.211,0 -4,-1.789 -4,-4 0,-2.211 1.789,-4 4,-4z"
android:fillColor="#f1fcff"/>
</vector>

View File

@ -1,61 +1,12 @@
<!--
~ Copyright (c) Kuba Szczodrzyński 2019-11-11.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="128dp" android:width="128dp"
android:height="128dp" android:height="128dp"
android:viewportWidth="128" android:viewportWidth="128"
android:viewportHeight="128"> android:viewportHeight="128">
<path <path
android:pathData="m117,76h4c3.852,0 7,-3.148 7,-7 0,-3.852 -3.148,-7 -7,-7h-13c-2.199,0 -4,-1.801 -4,-4s1.801,-4 4,-4h11c3.852,0 7,-3.148 7,-7 0,-3.852 -3.148,-7 -7,-7h-1c-2.211,0 -4,-1.789 -4,-4 0,-2.211 1.789,-4 4,-4h4c3.695,0 6.637,-3.387 5.879,-7.211 -0.566,-2.844 -3.238,-4.789 -6.141,-4.789h-15.738c-1.656,0 -3,-1.344 -3,-3s1.344,-3 3,-3h6.824c2.277,0 4.402,-1.441 4.992,-3.641 0.895,-3.328 -1.625,-6.359 -4.816,-6.359h-96c-3.852,0 -7,3.148 -7,7 0,3.852 3.148,7 7,7h3c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4h-10.77c-3.34,0 -6.391,2.242 -7.074,5.516 -0.941,4.488 2.508,8.484 6.844,8.484h15l-6,24h-10.77c-3.34,0 -6.391,2.242 -7.074,5.516 -0.941,4.488 2.508,8.484 6.844,8.484h1c2.211,0 4,1.789 4,4 0,2.211 -1.789,4 -4,4h-1c-4.336,0 -7.785,3.996 -6.844,8.484 0.684,3.273 3.734,5.516 7.074,5.516h10.77c2.211,0 4,1.789 4,4s-1.789,4 -4,4h-2.77c-3.34,0 -6.391,2.242 -7.074,5.516 -0.941,4.488 2.508,8.484 6.844,8.484h97c3.313,0 6,-2.688 6,-6s-2.688,-6 -6,-6h-1c-2.762,0 -5,-2.238 -5,-5s2.238,-5 5,-5h6c3.852,0 7,-3.148 7,-7 0,-3.852 -3.148,-7 -7,-7 -2.75,0 -5,-2.25 -5,-5s2.25,-5 5,-5z"> android:pathData="m103.24,15.168 l-7.883,7.871c-8.746,-7.063 -19.719,-11.039 -31.355,-11.039 -27.57,0 -50,22.43 -50,50s22.43,50 50,50c17.758,0 34.348,-9.367 43.301,-24.449 1.41,-2.375 0.625,-5.441 -1.75,-6.852 -2.367,-1.41 -5.438,-0.629 -6.852,1.746 -7.156,12.062 -20.453,19.555 -34.699,19.555 -22.055,0 -40,-17.945 -40,-40s17.945,-40 40,-40c8.934,0 17.371,2.938 24.223,8.16l-9.063,9.047c-2.48,2.5 -0.719,6.762 2.801,6.762h24.039c2.199,0 4,-1.801 4,-4v-24c0,-3.52 -4.262,-5.301 -6.762,-2.801z"
<aapt:attr name="android:fillColor"> android:fillColor="#ffcf48"/>
<gradient
android:gradientRadius="100.522"
android:centerX="63.746"
android:centerY="71.138"
android:type="radial"
android:tileMode="mirror">
<item android:offset="0" android:color="#1F0FCCFF"/>
<item android:offset="0.1927" android:color="#1F0FCEFF"/>
<item android:offset="0.7025" android:color="#1F0FD5FF"/>
<item android:offset="1" android:color="#1F0FD7FF"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m103.24,15.168 l-7.883,7.871c-8.746,-7.063 -19.719,-11.039 -31.355,-11.039 -27.57,0 -50,22.43 -50,50 0,27.57 22.43,50 50,50 17.758,0 34.348,-9.367 43.301,-24.449 1.41,-2.375 0.625,-5.441 -1.75,-6.852 -2.367,-1.41 -5.438,-0.629 -6.852,1.746 -7.156,12.062 -20.453,19.555 -34.699,19.555 -22.055,0 -40,-17.945 -40,-40 0,-22.055 17.945,-40 40,-40 8.934,0 17.371,2.938 24.223,8.16l-9.063,9.047c-2.48,2.5 -0.719,6.762 2.801,6.762h24.039c2.199,0 4,-1.801 4,-4v-24c0,-3.52 -4.262,-5.301 -6.762,-2.801z"> android:pathData="m68,85c0,2.762 -2.238,5 -5,5s-5,-2.238 -5,-5 2.238,-5 5,-5 5,2.238 5,5zM70,41c0,-3.867 -3.133,-7 -7,-7s-7,3.133 -7,7c0,0.047 0.016,0.094 0.016,0.141h-0.016l2.438,28.59c0.203,2.414 2.188,4.269 4.563,4.269s4.359,-1.855 4.563,-4.269l2.438,-28.59h-0.016c0,-0.047 0.016,-0.094 0.016,-0.141z"
<aapt:attr name="android:fillColor"> android:fillColor="#fd657a"/>
<gradient
android:startY="125.452"
android:startX="62"
android:endY="6.4762"
android:endX="62"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFEAA53"/>
<item android:offset="0.6124" android:color="#FFFFCD49"/>
<item android:offset="1" android:color="#FFFFDE44"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m68,85c0,2.762 -2.238,5 -5,5s-5,-2.238 -5,-5 2.238,-5 5,-5 5,2.238 5,5zM70,41c0,-3.867 -3.133,-7 -7,-7 -3.867,0 -7,3.133 -7,7 0,0.047 0.016,0.094 0.016,0.141h-0.016l2.438,28.59c0.203,2.414 2.188,4.269 4.563,4.269s4.359,-1.855 4.563,-4.269l2.438,-28.59h-0.016c0,-0.047 0.016,-0.094 0.016,-0.141z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="90"
android:startX="63"
android:endY="11.7176"
android:endX="63"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFF634D"/>
<item android:offset="0.2043" android:color="#FFFE6464"/>
<item android:offset="0.5209" android:color="#FFFC6581"/>
<item android:offset="0.7936" android:color="#FFFA6694"/>
<item android:offset="0.9892" android:color="#FFFA669A"/>
</gradient>
</aapt:attr>
</path>
</vector> </vector>

View File

@ -1,45 +1,5 @@
<!--
~ Copyright (c) Kuba Szczodrzyński 2019-11-11.
-->
<vector android:height="128dp" android:viewportHeight="64" <vector android:height="128dp" android:viewportHeight="64"
android:viewportWidth="64" android:width="128dp" android:viewportWidth="64" android:width="128dp" xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:aapt="http://schemas.android.com/aapt" xmlns:android="http://schemas.android.com/apk/res/android"> <path android:fillColor="#fd646f" android:pathData="m51.483,15.326 l3.937,-3.93c1.24,-1.25 0.36,-3.38 -1.4,-3.38h-12.02c-1.1,0 -2,0.9 -2,2v12c0,1.76 2.13,2.65 3.38,1.4l4.537,-4.529c2.615,3.426 4.083,7.646 4.083,12.113 0,11.215 -8.565,20 -19.5,20 -1.381,0 -2.5,1.119 -2.5,2.5s1.119,2.5 2.5,2.5c13.738,0 24.5,-10.981 24.5,-25 0,-5.817 -1.988,-11.301 -5.517,-15.674z"/>
<path android:pathData="m59,16h2c1.848,0 3.319,-1.693 2.94,-3.605 -0.283,-1.423 -1.62,-2.395 -3.071,-2.395h-10.369c-0.828,0 -1.5,-0.672 -1.5,-1.5s0.672,-1.5 1.5,-1.5h5.912c1.139,0 2.202,-0.721 2.497,-1.821 0.446,-1.663 -0.813,-3.179 -2.409,-3.179h-48c-1.925,0 -3.5,1.575 -3.5,3.5s1.575,3.5 3.5,3.5h1.5c1.105,0 2,0.895 2,2s-0.895,2 -2,2h-5.385c-1.67,0 -3.195,1.122 -3.537,2.757 -0.47,2.245 1.254,4.243 3.422,4.243h7.5l-3,12h-5.385c-1.67,0 -3.195,1.122 -3.537,2.757 -0.47,2.245 1.254,4.243 3.422,4.243h0.5c1.105,0 2,0.895 2,2s-0.895,2 -2,2h-0.5c-2.168,0 -3.892,1.998 -3.422,4.243 0.342,1.635 1.867,2.757 3.537,2.757h5.385c1.105,0 2,0.895 2,2s-0.895,2 -2,2h-1.385c-1.67,0 -3.195,1.122 -3.537,2.757 -0.47,2.245 1.254,4.243 3.422,4.243h48.5c1.657,0 3,-1.343 3,-3s-1.343,-3 -3,-3h-0.5c-1.381,0 -2.5,-1.119 -2.5,-2.5s1.119,-2.5 2.5,-2.5h4.5c1.657,0 3,-1.343 3,-3s-1.343,-3 -3,-3h-8.377c2.141,-3.494 3.377,-7.602 3.377,-12 0,-2.441 -0.384,-4.792 -1.088,-7h6.501c1.139,0 2.202,-0.721 2.497,-1.821 0.445,-1.663 -0.814,-3.179 -2.41,-3.179h-1.5c-1.105,0 -2,-0.895 -2,-2s0.895,-2 2,-2z"> <path android:fillColor="#fd646f" android:pathData="m20.604,38.58 l-4.523,4.53c-2.613,-3.427 -4.081,-7.647 -4.081,-12.11 0,-11.215 8.565,-20 19.5,-20 1.381,0 2.5,-1.119 2.5,-2.5s-1.119,-2.5 -2.5,-2.5c-13.738,0 -24.5,10.981 -24.5,25 0,5.815 1.989,11.303 5.52,15.677l-3.936,3.943c-1.25,1.25 -0.36,3.38 1.4,3.38h12c1.1,0 2,-0.9 2,-2v-12.02c0,-1.76 -2.13,-2.64 -3.38,-1.4z"/>
<aapt:attr name="android:fillColor">
<gradient android:centerX="32" android:centerY="31.500021"
android:gradientRadius="32" android:tileMode="mirror" android:type="radial">
<item android:color="#1F0FCCFF" android:offset="0"/>
<item android:color="#1F0FCEFF" android:offset="0.193"/>
<item android:color="#1F0FD5FF" android:offset="0.703"/>
<item android:color="#1F0ECEFF" android:offset="1"/>
</gradient>
</aapt:attr>
</path>
<path android:pathData="M51.483,15.326l3.937,-3.93c1.24,-1.25 0.36,-3.38 -1.4,-3.38H42c-1.1,0 -2,0.9 -2,2v12c0,1.76 2.13,2.65 3.38,1.4l4.537,-4.529C50.532,22.313 52,26.533 52,31c0,11.215 -8.565,20 -19.5,20c-1.381,0 -2.5,1.119 -2.5,2.5s1.119,2.5 2.5,2.5C46.238,56 57,45.019 57,31C57,25.183 55.012,19.699 51.483,15.326z">
<aapt:attr name="android:fillColor">
<gradient android:endX="43.5" android:endY="-21.15"
android:startX="43.5" android:startY="59.034"
android:tileMode="mirror" android:type="linear">
<item android:color="#FFFF634D" android:offset="0"/>
<item android:color="#FFFE6464" android:offset="0.204"/>
<item android:color="#FFFC6581" android:offset="0.521"/>
<item android:color="#FFFA6694" android:offset="0.794"/>
<item android:color="#FFFA669A" android:offset="0.989"/>
</gradient>
</aapt:attr>
</path>
<path android:pathData="M20.604,38.58l-4.523,4.53C13.468,39.683 12,35.463 12,31c0,-11.215 8.565,-20 19.5,-20c1.381,0 2.5,-1.119 2.5,-2.5S32.881,6 31.5,6C17.762,6 7,16.981 7,31c0,5.815 1.989,11.303 5.52,15.677L8.584,50.62c-1.25,1.25 -0.36,3.38 1.4,3.38h12c1.1,0 2,-0.9 2,-2V39.98C23.984,38.22 21.854,37.34 20.604,38.58z">
<aapt:attr name="android:fillColor">
<gradient android:endX="20.5" android:endY="-24.844"
android:startX="20.5" android:startY="55.227"
android:tileMode="mirror" android:type="linear">
<item android:color="#FFFF634D" android:offset="0"/>
<item android:color="#FFFE6464" android:offset="0.204"/>
<item android:color="#FFFC6581" android:offset="0.521"/>
<item android:color="#FFFA6694" android:offset="0.794"/>
<item android:color="#FFFA669A" android:offset="0.989"/>
</gradient>
</aapt:attr>
</path>
</vector> </vector>

View File

@ -1,202 +1,30 @@
<!--
~ Copyright (c) Kuba Szczodrzyński 2019-11-11.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" <vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="128dp" android:width="128dp"
android:height="128dp" android:height="128dp"
android:viewportWidth="128" android:viewportWidth="128"
android:viewportHeight="128"> android:viewportHeight="128">
<path <path
android:pathData="m118,62.129h2.605c3.789,0 7.188,-2.84 7.383,-6.625 0.211,-4.035 -3,-7.375 -6.988,-7.375h-4.805c-1.965,0 -3.785,-1.328 -4.129,-3.262 -0.043,-0.25 -0.066,-0.5 -0.066,-0.746 0.004,-2.168 1.734,-3.93 3.887,-3.988 3.023,-0.082 5.731,-2.293 6.07,-5.297 0.027,-0.242 0.039,-0.477 0.039,-0.711 0,-3.313 -2.688,-5.996 -6,-5.996h-4.602c-0.434,0 -4.863,-0.035 -5.281,-0.105 -0.035,-0.008 -0.074,-0.016 -0.113,-0.023v18h-42v-18h25.715c0.438,-1.688 0.539,-3.512 -0.945,-5.719 -1.836,-2.742 -5.023,-4.281 -8.324,-4.281h-9.445c-1.656,0 -3,-1.344 -3,-3s1.344,-3 3,-3h0.66c3.25,0 6.16,-2.434 6.332,-5.68 0.18,-3.461 -2.57,-6.32 -5.992,-6.32h-57.66c-3.25,0 -6.16,2.434 -6.332,5.68 -0.18,3.457 2.57,6.32 5.992,6.32h15c1.656,0 3,1.344 3,3s-1.344,3 -3,3h-17c-4.418,0 -8,3.582 -8,8s3.582,8 8,8h26v12h-14l2,21.109c-1.07,0.801 -1.836,1.98 -1.973,3.375 -0.184,1.84 0.633,3.5 1.973,4.504v5.047c-0.027,0.148 -0.043,0.297 -0.027,0.449 0.301,2.992 -2.039,5.516 -4.973,5.516h-14.66c-2.984,0 -5.762,2.023 -6.25,4.965 -0.246,1.465 0.043,2.848 0.684,4.012 1.074,1.938 3.234,3.023 5.449,3.023h3.164c2.375,0 4.207,1.328 4.551,3.27 0.039,0.246 0.063,0.488 0.063,0.723 0.004,2.215 -1.789,4.008 -3.996,4.008h-0.004c-2.27,0 -4.473,1.203 -5.398,3.277 -1.98,4.426 1.207,8.723 5.398,8.723h62c3.313,0 6,-2.688 6,-6s-2.688,-6 -6,-6h-10v-20l46,0.129h9.66c3.141,0 6.168,-2.539 6.328,-5.676 0.184,-3.461 -2.57,-6.324 -5.992,-6.324h-0.023,-0.035c-1.555,0 -3.078,-0.508 -4.156,-1.535 -0.34,-0.324 -0.637,-0.699 -0.875,-1.129 -2.574,-4.637 0.711,-9.336 5.094,-9.336z"> android:pathData="m18,100v-60h92v60c0,5.523 -4.477,10 -10,10h-72c-5.523,0 -10,-4.477 -10,-10z"
<aapt:attr name="android:fillColor"> android:fillColor="#ffc662"/>
<gradient
android:gradientRadius="80.322"
android:centerX="60.334"
android:centerY="65.146"
android:type="radial"
android:tileMode="mirror">
<item android:offset="0" android:color="#1F0FCCFF"/>
<item android:offset="0.1927" android:color="#1F0FCEFF"/>
<item android:offset="0.7025" android:color="#1F0FD5FF"/>
<item android:offset="1" android:color="#1F0FD7FF"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m18,100v-60h92v60c0,5.523 -4.477,10 -10,10h-72c-5.523,0 -10,-4.477 -10,-10z"> android:pathData="m110,29.602v16.398h-92v-16.398c0,-5.309 4.332,-9.602 9.684,-9.602h72.633c5.352,0 9.684,4.293 9.684,9.602"
<aapt:attr name="android:fillColor"> android:fillColor="#ff634f"/>
<gradient
android:startY="110"
android:startX="64"
android:endY="40"
android:endX="64"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFFC662"/>
<item android:offset="0.0036" android:color="#FFFFC662"/>
<item android:offset="0.6085" android:color="#FFFFC582"/>
<item android:offset="1" android:color="#FFFFC491"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m110,29.602v16.398h-92v-16.398c0,-5.309 4.332,-9.602 9.684,-9.602h72.633c5.352,0 9.684,4.293 9.684,9.602"> android:pathData="m43,34c-2.75,0 -5,-2.25 -5,-5v-12c0,-2.75 2.25,-5 5,-5s5,2.25 5,5v12c0,2.75 -2.25,5 -5,5z"
<aapt:attr name="android:fillColor"> android:fillColor="#888"/>
<gradient
android:startY="46"
android:startX="64"
android:endY="20"
android:endX="64"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFF634D"/>
<item android:offset="0.2083" android:color="#FFFD6464"/>
<item android:offset="0.5223" android:color="#FFFC6582"/>
<item android:offset="0.7935" android:color="#FFFA6694"/>
<item android:offset="0.9892" android:color="#FFFA669A"/>
<item android:offset="1" android:color="#FFFA669A"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m49.309,20h-12.621c-2.832,1.988 -4.688,5.277 -4.688,9 0,6.07 4.93,11 11,11 6.07,0 11,-4.93 11,-11 0,-3.723 -1.855,-7.012 -4.691,-9z"> android:pathData="m85,34c-2.75,0 -5,-2.25 -5,-5v-12c0,-2.75 2.25,-5 5,-5s5,2.25 5,5v12c0,2.75 -2.25,5 -5,5z"
<aapt:attr name="android:fillColor"> android:fillColor="#888"/>
<gradient
android:startY="40"
android:startX="43"
android:endY="20"
android:endX="43"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFF5840"/>
<item android:offset="0.0072" android:color="#FFFF5840"/>
<item android:offset="0.9892" android:color="#FFFA528C"/>
<item android:offset="1" android:color="#FFFA528C"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m43,34c-2.75,0 -5,-2.25 -5,-5v-12c0,-2.75 2.25,-5 5,-5s5,2.25 5,5v12c0,2.75 -2.25,5 -5,5z"> android:pathData="m48,74h-8c-2.211,0 -4,-1.789 -4,-4v-8c0,-2.211 1.789,-4 4,-4h8c2.211,0 4,1.789 4,4v8c0,2.211 -1.789,4 -4,4zM72,70v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM92,70v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM52,90v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM72,90v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM92,90v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4z"
<aapt:attr name="android:fillColor"> android:fillColor="#ffe79f"/>
<gradient
android:startY="12"
android:startX="43"
android:endY="34"
android:endX="43"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFA4A4A4"/>
<item android:offset="0.6301" android:color="#FF7F7F7F"/>
<item android:offset="1" android:color="#FF6F6F6F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m91.309,20h-12.621c-2.832,1.988 -4.688,5.277 -4.688,9 0,6.07 4.93,11 11,11 6.07,0 11,-4.93 11,-11 0,-3.723 -1.855,-7.012 -4.691,-9z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="40"
android:startX="85"
android:endY="20"
android:endX="85"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFF5840"/>
<item android:offset="0.0072" android:color="#FFFF5840"/>
<item android:offset="0.9892" android:color="#FFFA528C"/>
<item android:offset="1" android:color="#FFFA528C"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m85,34c-2.75,0 -5,-2.25 -5,-5v-12c0,-2.75 2.25,-5 5,-5s5,2.25 5,5v12c0,2.75 -2.25,5 -5,5z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="12"
android:startX="85"
android:endY="34"
android:endX="85"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFA4A4A4"/>
<item android:offset="0.6301" android:color="#FF7F7F7F"/>
<item android:offset="1" android:color="#FF6F6F6F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m78,81.008c0,2.762 2.238,5 5,4.996h2.992c3.316,-0.008 6.008,2.684 6.008,5.996s-2.688,6 -6,6h-8c-3.313,0 -6,2.688 -6,6s2.688,6 6,6h22c5.523,0 10,-4.477 10,-10v-24l-27.008,0.012c-2.758,-0 -4.992,2.234 -4.992,4.996z"
android:fillColor="#ffb86a"/>
<path
android:pathData="m18,68h17.785c1.992,0 3.84,-1.363 4.16,-3.328 0.406,-2.508 -1.516,-4.672 -3.945,-4.672h-3c-1.656,0 -3,-1.344 -3,-3s1.344,-3 3,-3h14.785c1.992,0 3.84,-1.363 4.16,-3.328 0.406,-2.508 -1.516,-4.672 -3.945,-4.672h-30z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="108.25"
android:startX="35"
android:endY="43.742"
android:endX="35"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFFCE76"/>
<item android:offset="0.0036" android:color="#FFFFCE76"/>
<item android:offset="0.6054" android:color="#FFFFCD92"/>
<item android:offset="1" android:color="#FFFFCCA0"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="m98,62c0,3.313 -2.688,6 -6,6s-6,-2.688 -6,-6 2.688,-6 6,-6 6,2.688 6,6z"
android:fillColor="#ffb977"/>
<path
android:pathData="m48,74h-8c-2.211,0 -4,-1.789 -4,-4v-8c0,-2.211 1.789,-4 4,-4h8c2.211,0 4,1.789 4,4v8c0,2.211 -1.789,4 -4,4zM72,70v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM92,70v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM52,90v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM72,90v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4zM92,90v-8c0,-2.211 -1.789,-4 -4,-4h-8c-2.211,0 -4,1.789 -4,4v8c0,2.211 1.789,4 4,4h8c2.211,0 4,-1.789 4,-4z">
<aapt:attr name="android:fillColor">
<gradient
android:startY="94"
android:startX="64"
android:endY="58"
android:endX="64"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FFFFE79F"/>
<item android:offset="0.1186" android:color="#FFFFE9A6"/>
<item android:offset="1" android:color="#FFFFF5D5"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m124,104c0,11.047 -8.953,20 -20,20 -11.047,0 -20,-8.953 -20,-20 0,-11.047 8.953,-20 20,-20 11.047,0 20,8.953 20,20z" android:pathData="m124,104c0,11.047 -8.953,20 -20,20 -11.047,0 -20,-8.953 -20,-20 0,-11.047 8.953,-20 20,-20 11.047,0 20,8.953 20,20z"
android:fillColor="#fff"/> android:fillColor="#fff"/>
<path <path
android:pathData="m104,80c-13.254,0 -24,10.746 -24,24 0,13.254 10.746,24 24,24 13.254,0 24,-10.746 24,-24 0,-13.254 -10.746,-24 -24,-24zM104,120c-8.836,0 -16,-7.164 -16,-16 0,-8.836 7.164,-16 16,-16 8.836,0 16,7.164 16,16 0,8.836 -7.164,16 -16,16z"> android:pathData="m104,80c-13.254,0 -24,10.746 -24,24 0,13.254 10.746,24 24,24 13.254,0 24,-10.746 24,-24 0,-13.254 -10.746,-24 -24,-24zM104,120c-8.836,0 -16,-7.164 -16,-16 0,-8.836 7.164,-16 16,-16 8.836,0 16,7.164 16,16 0,8.836 -7.164,16 -16,16z"
<aapt:attr name="android:fillColor"> android:fillColor="#1f80e5"/>
<gradient
android:startY="128"
android:startX="104"
android:endY="80"
android:endX="104"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FF155CDE"/>
<item android:offset="0.6248" android:color="#FF2289E7"/>
<item android:offset="1" android:color="#FF289FEC"/>
</gradient>
</aapt:attr>
</path>
<path <path
android:pathData="m113.41,110.59 l-5.563,-5.563c0.086,-0.328 0.148,-0.668 0.148,-1.023 0,-1.477 -0.809,-2.754 -2,-3.445v-6.555c0,-1.105 -0.895,-2 -2,-2s-2,0.895 -2,2v6.555c-1.191,0.691 -2,1.969 -2,3.445 0,2.211 1.789,4 4,4 0.355,0 0.695,-0.063 1.023,-0.148l5.563,5.563c0.391,0.391 0.902,0.586 1.414,0.586s1.023,-0.195 1.414,-0.586c0.781,-0.781 0.781,-2.047 0,-2.828z"> android:pathData="m113.41,110.59 l-5.563,-5.563c0.086,-0.328 0.148,-0.668 0.148,-1.023 0,-1.477 -0.809,-2.754 -2,-3.445v-6.555c0,-1.105 -0.895,-2 -2,-2s-2,0.895 -2,2v6.555c-1.191,0.691 -2,1.969 -2,3.445 0,2.211 1.789,4 4,4 0.355,0 0.695,-0.063 1.023,-0.148l5.563,5.563c0.391,0.391 0.902,0.586 1.414,0.586s1.023,-0.195 1.414,-0.586c0.781,-0.781 0.781,-2.047 0,-2.828z"
<aapt:attr name="android:fillColor"> android:fillColor="#919191"/>
<gradient
android:startY="92"
android:startX="107"
android:endY="114"
android:endX="107"
android:type="linear"
android:tileMode="mirror">
<item android:offset="0" android:color="#FF919191"/>
<item android:offset="1" android:color="#FF6F6F6F"/>
</gradient>
</aapt:attr>
</path>
</vector> </vector>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) Kacper Ziubryniewicz 2019-11-23
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@color/red500"/>
<size android:width="10dp" android:height="10dp"/>
</shape>

View File

@ -117,7 +117,7 @@
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:hint="@string/dialog_event_manual_topic"> android:hint="@string/dialog_event_manual_topic">
<com.google.android.material.textfield.TextInputEditText <pl.szczodrzynski.edziennik.utils.TextInputKeyboardEdit
android:id="@+id/topic" android:id="@+id/topic"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -1,35 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout 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">
<androidx.constraintlayout.widget.ConstraintLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/notificationsView" android:id="@+id/notificationsView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
tools:listitem="@layout/row_notifications_item"
</androidx.recyclerview.widget.RecyclerView> tools:visibility="gone" />
<TextView <TextView
android:id="@+id/notificationsNoData" android:id="@+id/notificationsNoData"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_gravity="center"
android:layout_marginLeft="8dp" android:drawableTop="@drawable/ic_no_notifications"
android:layout_marginTop="8dp" android:drawablePadding="16dp"
android:layout_marginEnd="8dp" android:fontFamily="sans-serif-light"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:text="@string/notifications_no_data" android:text="@string/notifications_no_data"
android:textSize="18sp" android:textSize="24sp"
android:textStyle="italic"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" tools:visibility="visible" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </FrameLayout>
</layout> </layout>

View File

@ -1,75 +1,35 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout 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" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical"
android:padding="8dp"
android:background="?selectableItemBackground">
<com.google.android.material.card.MaterialCardView <TextView
android:id="@+id/notificationsItemCard" android:id="@+id/title"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_margin="8dp" android:textAppearance="@style/NavView.TextView.Medium"
android:background="?selectableItemBackground" tools:text="Dzisiaj 1 to szczęśliwy numerek" />
app:cardElevation="4dp"
app:cardCornerRadius="5dp"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="3dp">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content">
android:background="?selectableItemBackground"
android:orientation="vertical"
android:padding="8dp">
<TextView <TextView
android:id="@+id/notificationsItemDate" android:id="@+id/profileDate"
android:layout_width="match_parent" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:layout_weight="1"
android:textSize="16sp" tools:text="Władca Androida • 22 listopada" />
tools:text="date" />
<LinearLayout <TextView
android:layout_width="match_parent" android:id="@+id/type"
android:layout_height="wrap_content" android:layout_width="wrap_content"
android:orientation="horizontal"> android:layout_height="wrap_content"
tools:text="Szczęśliwy numerek" />
<TextView </LinearLayout>
android:id="@+id/notificationsItemText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:autoLink="all"
tools:text="text" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/notificationsItemTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
tools:text="title" />
<TextView
android:id="@+id/notificationsItemType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
tools:text="type" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout> </LinearLayout>

View File

@ -11,6 +11,9 @@
<variable <variable
name="lessonNumber" name="lessonNumber"
type="Integer" /> type="Integer" />
<variable
name="unread"
type="boolean" />
</data> </data>
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -70,6 +73,17 @@
tools:maxLines="2" tools:maxLines="2"
tools:text="pracownia urządzeń techniki komputerowej" /> tools:text="pracownia urządzeń techniki komputerowej" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingStart="8dp"
android:paddingLeft="8dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:visibility="@{unread ? View.VISIBLE : View.GONE}"
app:srcCompat="@drawable/unread_red_circle" />
<ImageView <ImageView
android:id="@+id/attendanceIcon" android:id="@+id/attendanceIcon"
android:layout_width="24dp" android:layout_width="24dp"
@ -136,4 +150,4 @@
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>
</layout> </layout>

View File

@ -547,7 +547,7 @@
<string name="settings_about_licenses_text">Open-source licenses</string> <string name="settings_about_licenses_text">Open-source licenses</string>
<string name="settings_about_privacy_policy_text">Privacy policy</string> <string name="settings_about_privacy_policy_text">Privacy policy</string>
<string name="settings_about_register_title_text">E-register</string> <string name="settings_about_register_title_text">E-register</string>
<string name="settings_about_title_subtext">© Kuba Szczodrzyński September 2018 - October 2019</string> <string name="settings_about_title_subtext">© Kuba Szczodrzyński &amp;&amp; Kacper Ziubryniewicz\nSeptember 2018 - November 2019</string>
<string name="settings_about_update_subtext">Click to check for updates</string> <string name="settings_about_update_subtext">Click to check for updates</string>
<string name="settings_about_update_text">Update</string> <string name="settings_about_update_text">Update</string>
<string name="settings_about_version_text">Version</string> <string name="settings_about_version_text">Version</string>

View File

@ -593,7 +593,7 @@
<string name="settings_about_licenses_text">Licencje open-source</string> <string name="settings_about_licenses_text">Licencje open-source</string>
<string name="settings_about_privacy_policy_text">Polityka prywatności</string> <string name="settings_about_privacy_policy_text">Polityka prywatności</string>
<string name="settings_about_register_title_text">E-dziennik</string> <string name="settings_about_register_title_text">E-dziennik</string>
<string name="settings_about_title_subtext">© Kuba Szczodrzyński wrzesień 2018 - październik 2019</string> <string name="settings_about_title_subtext">© Kuba Szczodrzyński &amp;&amp; Kacper Ziubryniewicz\nwrzesień 2018 - listopad 2019</string>
<string name="settings_about_update_subtext">Kliknij, aby sprawdzić aktualizacje</string> <string name="settings_about_update_subtext">Kliknij, aby sprawdzić aktualizacje</string>
<string name="settings_about_update_text">Aktualizacja</string> <string name="settings_about_update_text">Aktualizacja</string>
<string name="settings_about_version_text">Wersja</string> <string name="settings_about_version_text">Wersja</string>
@ -1028,4 +1028,7 @@
<string name="timetable_no_subject_name">(brak nazwy)</string> <string name="timetable_no_subject_name">(brak nazwy)</string>
<string name="dialog_event_manual_more_options">Więcej opcji</string> <string name="dialog_event_manual_more_options">Więcej opcji</string>
<string name="edziennik_progress_endpoint_grade_comments">Pobieranie komentarzy ocen...</string> <string name="edziennik_progress_endpoint_grade_comments">Pobieranie komentarzy ocen...</string>
<string name="menu_remove_notifications">Usuń wszystkie</string>
<string name="menu_remove_notifications_success">Wyczyszczono powiadomienia</string>
<string name="timetable_select_day">Wybierz dzień</string>
</resources> </resources>

View File

@ -5,8 +5,8 @@ buildscript {
kotlin_version = '1.3.50' kotlin_version = '1.3.50'
release = [ release = [
versionName: "3.9.9-dev", versionName: "3.9.10-dev",
versionCode: 3090900 versionCode: 3091000
] ]
setup = [ setup = [
@ -59,7 +59,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.1' classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'me.tatarka:gradle-retrolambda:3.7.0' classpath 'me.tatarka:gradle-retrolambda:3.7.0'
classpath 'com.google.gms:google-services:4.3.1' classpath 'com.google.gms:google-services:4.3.1'
classpath 'io.fabric.tools:gradle:1.28.1' classpath 'io.fabric.tools:gradle:1.28.1'

View File

@ -1,4 +1,4 @@
include ':app', ':agendacalendarview', ':mhttp', ':material-about-library', ':cafebar', ':szkolny-font', ':nachos' include ':app', ':agendacalendarview', ':mhttp', ':material-about-library', ':cafebar', ':szkolny-font', ':nachos', ':community-material'
/* /*
include ':Navigation' include ':Navigation'
project(':Navigation').projectDir = new File(settingsDir, '../Navigation/navlib')*/ project(':Navigation').projectDir = new File(settingsDir, '../Navigation/navlib')*/

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2014 Mike Penz * Copyright 2019 Mike Penz
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,8 +26,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
consumerProguardFiles 'consumer-proguard-rules.pro' consumerProguardFiles 'consumer-proguard-rules.pro'
versionCode 1 versionCode 11
versionName "1.0" versionName "1.1"
} }
buildTypes { buildTypes {
release { release {
@ -47,5 +47,5 @@ if (project.hasProperty('pushall') || project.hasProperty('SzkolnyFontonly')) {
dependencies { dependencies {
implementation "com.mikepenz:iconics-core:${iconics}" implementation "com.mikepenz:iconics-core:${iconics}"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
} }

View File

@ -1,6 +1,5 @@
/* /*
* Copyright 2014 Mike Penz * Copyright 2019 Mike Penz
* Copyright 2015 Haruki Hasegawa
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,21 +18,18 @@ package com.mikepenz.iconics.typeface.library.szkolny.font
import com.mikepenz.iconics.typeface.IIcon import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.ITypeface import com.mikepenz.iconics.typeface.ITypeface
import com.mikepenz.iconics.typeface.library.szkolny.R import com.mikepenz.iconics.typeface.library.szkolny.R
import java.util.LinkedList import java.util.*
@Suppress("EnumEntryName") @Suppress("EnumEntryName")
object SzkolnyFont : ITypeface { object SzkolnyFont : ITypeface {
override val fontRes: Int override val fontRes: Int
get() = R.font.szkolny_font_font_v1_0 get() = R.font.szkolny_font_font_v1_1
override val characters: Map<String, Char> by lazy { override val characters: Map<String, Char> by lazy {
mutableMapOf<String, Char>().apply { Icon.values().associate { it.name to it.character }
SzkolnyFont.Icon.values().associateTo(this) { it.name to it.character }
//Icon2.values().associateTo(this) { it.name to it.character }
}
} }
override val mappingPrefix: String override val mappingPrefix: String
get() = "szf" get() = "szf"
@ -41,7 +37,7 @@ object SzkolnyFont : ITypeface {
get() = "Szkolny Font" get() = "Szkolny Font"
override val version: String override val version: String
get() = "1.0" get() = "1.1"
override val iconCount: Int override val iconCount: Int
get() = characters.size get() = characters.size
@ -64,17 +60,28 @@ object SzkolnyFont : ITypeface {
override val licenseUrl: String override val licenseUrl: String
get() = "" get() = ""
override fun getIcon(key: String): IIcon { override fun getIcon(key: String): IIcon = Icon.valueOf(key)
return SzkolnyFont.Icon.valueOf(key)
}
enum class Icon constructor(override val character: Char) : IIcon { enum class Icon constructor(override val character: Char) : IIcon {
szf_eye_check('\ue800'), szf_alarm_bell_outline('\ue800'),
szf_calendar_off('\ue801'), szf_calendar_plus_outline('\ue801'),
szf_file_document_edit('\ue802'), szf_calendar_today_outline('\ue802'),
szf_message_off('\ue803'), szf_clipboard_list_outline('\ue803'),
szf_numeric_0_box_multiple_outline_off('\ue804'); szf_delete_empty_outline('\ue804'),
szf_discord_outline('\ue805'),
szf_file_code_outline('\ue806'),
szf_file_excel_outline('\ue807'),
szf_file_image_outline('\ue808'),
szf_file_music_outline('\ue809'),
szf_file_pdf_outline('\ue80a'),
szf_file_percent_outline('\ue80b'),
szf_file_powerpoint_outline('\ue80c'),
szf_file_video_outline('\ue80d'),
szf_file_word_outline('\ue80e'),
szf_message_processing_outline('\ue80f'),
szf_notebook_outline('\ue810'),
szf_zip_box_outline('\ue811');
override val typeface: ITypeface by lazy { SzkolnyFont } override val typeface: ITypeface by lazy { SzkolnyFont }
} }
} }