mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-15 23:11:54 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
ccf0bdaf05 | |||
4647da7803 | |||
613f271c4e | |||
8b1529f240 | |||
3eb09033bf | |||
95baf9fb9c | |||
dd0972b528 |
3
.github/workflows/build-release-aab-play.yml
vendored
3
.github/workflows/build-release-aab-play.yml
vendored
@ -113,12 +113,11 @@ jobs:
|
|||||||
releaseFile: ${{ needs.sign.outputs.signedReleaseFile }}
|
releaseFile: ${{ needs.sign.outputs.signedReleaseFile }}
|
||||||
releaseName: ${{ steps.changelog.outputs.appVersionName }}
|
releaseName: ${{ steps.changelog.outputs.appVersionName }}
|
||||||
track: ${{ secrets.PLAY_RELEASE_TRACK }}
|
track: ${{ secrets.PLAY_RELEASE_TRACK }}
|
||||||
userFraction: 1.0
|
|
||||||
whatsNewDirectory: ${{ steps.changelog.outputs.changelogDir }}
|
whatsNewDirectory: ${{ steps.changelog.outputs.changelogDir }}
|
||||||
|
|
||||||
- name: Upload workflow artifact
|
- name: Upload workflow artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
if: true
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.changelog.outputs.appVersionName }}
|
name: ${{ steps.changelog.outputs.appVersionName }}
|
||||||
path: |
|
path: |
|
||||||
|
9
.idea/codeStyles/Project.xml
generated
9
.idea/codeStyles/Project.xml
generated
@ -15,6 +15,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>xmlns:android</NAME>
|
<NAME>xmlns:android</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -25,6 +26,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>xmlns:.*</NAME>
|
<NAME>xmlns:.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -36,6 +38,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*:id</NAME>
|
<NAME>.*:id</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -46,6 +49,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*:name</NAME>
|
<NAME>.*:name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -56,6 +60,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>name</NAME>
|
<NAME>name</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -66,6 +71,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>style</NAME>
|
<NAME>style</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -76,6 +82,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -87,6 +94,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
@ -98,6 +106,7 @@
|
|||||||
<match>
|
<match>
|
||||||
<AND>
|
<AND>
|
||||||
<NAME>.*</NAME>
|
<NAME>.*</NAME>
|
||||||
|
<XML_ATTRIBUTE />
|
||||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||||
</AND>
|
</AND>
|
||||||
</match>
|
</match>
|
||||||
|
3
app/proguard-rules.pro
vendored
3
app/proguard-rules.pro
vendored
@ -32,8 +32,9 @@
|
|||||||
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
-keepnames class pl.szczodrzynski.edziennik.ui.widgets.luckynumber.WidgetLuckyNumberProvider
|
||||||
|
|
||||||
-keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); }
|
-keepnames class androidx.appcompat.view.menu.MenuBuilder { setHeaderTitleInt(java.lang.CharSequence); }
|
||||||
-keepclassmembernames class androidx.appcompat.view.menu.StandardMenuPopup { private *; }
|
|
||||||
-keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); }
|
-keepnames class androidx.appcompat.view.menu.MenuPopupHelper { showPopup(int, int, boolean, boolean); }
|
||||||
|
-keepclassmembernames class androidx.appcompat.view.menu.StandardMenuPopup { private *; }
|
||||||
|
-keepclassmembernames class androidx.appcompat.view.menu.MenuItemImpl { private *; }
|
||||||
|
|
||||||
-keepclassmembernames class com.mikepenz.materialdrawer.widget.MiniDrawerSliderView { private *; }
|
-keepclassmembernames class com.mikepenz.materialdrawer.widget.MiniDrawerSliderView { private *; }
|
||||||
|
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
<h3>Wersja 4.7, 2021-04-07</h3>
|
<h3>Wersja 4.7.1, 2021-04-12</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><u>Szkolny.eu jest teraz open source!</u> Zapraszamy na stronę <a href="https://szkolny.eu/">https://szkolny.eu/</a> po więcej ważnych informacji.</li>
|
<li>Poprawiono sprawdzanie dostępności e-dziennika.</li>
|
||||||
<li>Poprawiono wybieranie obrazków (tła nagłówka, tła aplikacji oraz profilu) z dowolnego źródła.</li>
|
<li>Zmieniono datę w informacjach o aplikacji. @Luncenok</li>
|
||||||
<li>Ukończono tłumaczenie na język angielski. @MarcinK50</li>
|
|
||||||
<li>Dodano ekran informacji o kompilacji w Ustawieniach.</li>
|
|
||||||
<li>Zaktualizowano ekran licencji open source.</li>
|
|
||||||
<li>Naprawiono zatrzymanie aplikacji na Androidzie 4.4 i starszych.</li>
|
|
||||||
<li>Naprawiono problemy z połączeniem internetowym na Androidzie 4.4 i starszych.</li>
|
|
||||||
<li>Zoptymalizowano wielkość aplikacji.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/*secret password - removed for source code publication*/
|
/*secret password - removed for source code publication*/
|
||||||
static toys AES_IV[16] = {
|
static toys AES_IV[16] = {
|
||||||
0xda, 0x9f, 0xd4, 0x2b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
0xcc, 0x64, 0xdb, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||||
|
|
||||||
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
unsigned char *agony(unsigned int laugh, unsigned char *box, unsigned char *heat);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ package pl.szczodrzynski.edziennik.config
|
|||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.reflect.TypeToken
|
import com.google.gson.reflect.TypeToken
|
||||||
|
import pl.szczodrzynski.edziennik.BuildConfig
|
||||||
import pl.szczodrzynski.edziennik.config.utils.get
|
import pl.szczodrzynski.edziennik.config.utils.get
|
||||||
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
import pl.szczodrzynski.edziennik.config.utils.getIntList
|
||||||
import pl.szczodrzynski.edziennik.config.utils.set
|
import pl.szczodrzynski.edziennik.config.utils.set
|
||||||
@ -123,6 +124,19 @@ class ConfigSync(private val config: Config) {
|
|||||||
|
|
||||||
private var mRegisterAvailability: Map<String, RegisterAvailabilityStatus>? = null
|
private var mRegisterAvailability: Map<String, RegisterAvailabilityStatus>? = null
|
||||||
var registerAvailability: Map<String, RegisterAvailabilityStatus>
|
var registerAvailability: Map<String, RegisterAvailabilityStatus>
|
||||||
get() { mRegisterAvailability = mRegisterAvailability ?: config.values.get("registerAvailability", null as String?)?.let { it -> gson.fromJson<Map<String, RegisterAvailabilityStatus>>(it, object: TypeToken<Map<String, RegisterAvailabilityStatus>>(){}.type) }; return mRegisterAvailability ?: mapOf() }
|
get() {
|
||||||
set(value) { config.setMap("registerAvailability", value); mRegisterAvailability = value }
|
val flavor = config.values.get("registerAvailabilityFlavor", null as String?)
|
||||||
|
if (BuildConfig.FLAVOR != flavor)
|
||||||
|
return mapOf()
|
||||||
|
|
||||||
|
mRegisterAvailability = mRegisterAvailability ?: config.values.get("registerAvailability", null as String?)?.let { it ->
|
||||||
|
gson.fromJson(it, object: TypeToken<Map<String, RegisterAvailabilityStatus>>(){}.type)
|
||||||
|
}
|
||||||
|
return mRegisterAvailability ?: mapOf()
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
config.setMap("registerAvailability", value)
|
||||||
|
config.set("registerAvailabilityFlavor", BuildConfig.FLAVOR)
|
||||||
|
mRegisterAvailability = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,6 @@ object Signing {
|
|||||||
|
|
||||||
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
|
/*fun provideKey(param1: String, param2: Long): ByteArray {*/
|
||||||
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
|
fun pleaseStopRightNow(param1: String, param2: Long): ByteArray {
|
||||||
return "$param1.MTIzNDU2Nzg5MDLPrcQX7M===.$param2".sha256()
|
return "$param1.MTIzNDU2Nzg5MDXHhAtZBW===.$param2".sha256()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,10 +199,14 @@ class EventDetailsDialog(
|
|||||||
}
|
}
|
||||||
b.downloadButton.attachToastHint(R.string.hint_download_again)
|
b.downloadButton.attachToastHint(R.string.hint_download_again)
|
||||||
|
|
||||||
|
BetterLink.attach(b.topic, onActionSelected = dialog::dismiss)
|
||||||
|
|
||||||
b.topic.text = event.topic
|
event.teacherName?.let { name ->
|
||||||
BetterLink.attach(b.topic) {
|
BetterLink.attach(
|
||||||
dialog.dismiss()
|
b.teacherName,
|
||||||
|
teachers = mapOf(event.teacherId to name),
|
||||||
|
onActionSelected = dialog::dismiss
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.homeworkBody == null && !event.addedManually && event.type == Event.TYPE_HOMEWORK) {
|
if (event.homeworkBody == null && !event.addedManually && event.type == Event.TYPE_HOMEWORK) {
|
||||||
@ -220,10 +224,7 @@ class EventDetailsDialog(
|
|||||||
b.bodyTitle.isVisible = true
|
b.bodyTitle.isVisible = true
|
||||||
b.bodyProgressBar.isVisible = false
|
b.bodyProgressBar.isVisible = false
|
||||||
b.body.isVisible = true
|
b.body.isVisible = true
|
||||||
b.body.text = event.homeworkBody
|
BetterLink.attach(b.body, onActionSelected = dialog::dismiss)
|
||||||
BetterLink.attach(b.body) {
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.attachmentIds.isNullOrEmpty() || event.attachmentNames.isNullOrEmpty()) {
|
if (event.attachmentIds.isNullOrEmpty() || event.attachmentNames.isNullOrEmpty()) {
|
||||||
|
@ -14,6 +14,7 @@ import pl.szczodrzynski.edziennik.databinding.DialogGradeDetailsBinding
|
|||||||
import pl.szczodrzynski.edziennik.onClick
|
import pl.szczodrzynski.edziennik.onClick
|
||||||
import pl.szczodrzynski.edziennik.setTintColor
|
import pl.szczodrzynski.edziennik.setTintColor
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesAdapter
|
import pl.szczodrzynski.edziennik.ui.modules.grades.GradesAdapter
|
||||||
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
@ -68,6 +69,14 @@ class GradeDetailsDialog(
|
|||||||
GradesConfigDialog(activity, reloadOnDismiss = true)
|
GradesConfigDialog(activity, reloadOnDismiss = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grade.teacherName?.let { name ->
|
||||||
|
BetterLink.attach(
|
||||||
|
b.teacherName,
|
||||||
|
teachers = mapOf(grade.teacherId to name),
|
||||||
|
onActionSelected = dialog::dismiss
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
launch {
|
launch {
|
||||||
val historyList = withContext(Dispatchers.Default) {
|
val historyList = withContext(Dispatchers.Default) {
|
||||||
app.db.gradeDao().getByParentIdNow(App.profileId, grade.id)
|
app.db.gradeDao().getByParentIdNow(App.profileId, grade.id)
|
||||||
|
@ -25,6 +25,7 @@ import pl.szczodrzynski.edziennik.ui.dialogs.event.EventDetailsDialog
|
|||||||
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventListAdapter
|
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventListAdapter
|
||||||
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
|
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
|
||||||
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
|
import pl.szczodrzynski.edziennik.ui.modules.timetable.TimetableFragment
|
||||||
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Week
|
import pl.szczodrzynski.edziennik.utils.models.Week
|
||||||
@ -216,5 +217,19 @@ class LessonDetailsDialog(
|
|||||||
b.eventsNoData.visibility = View.VISIBLE
|
b.eventsNoData.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
lesson.displayTeacherName?.let { name ->
|
||||||
|
lesson.displayTeacherId ?: return@let
|
||||||
|
BetterLink.attach(
|
||||||
|
b.teacherNameView,
|
||||||
|
teachers = mapOf(lesson.displayTeacherId!! to name),
|
||||||
|
onActionSelected = dialog::dismiss
|
||||||
|
)
|
||||||
|
BetterLink.attach(
|
||||||
|
b.oldTeacherNameView,
|
||||||
|
teachers = mapOf(lesson.displayTeacherId!! to name),
|
||||||
|
onActionSelected = dialog::dismiss
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import pl.szczodrzynski.edziennik.R
|
|||||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
||||||
import pl.szczodrzynski.edziennik.databinding.AttendanceDetailsDialogBinding
|
import pl.szczodrzynski.edziennik.databinding.AttendanceDetailsDialogBinding
|
||||||
import pl.szczodrzynski.edziennik.setTintColor
|
import pl.szczodrzynski.edziennik.setTintColor
|
||||||
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
class AttendanceDetailsDialog(
|
class AttendanceDetailsDialog(
|
||||||
@ -60,5 +61,13 @@ class AttendanceDetailsDialog(
|
|||||||
b.attendanceName.background.setTintColor(attendanceColor)
|
b.attendanceName.background.setTintColor(attendanceColor)
|
||||||
|
|
||||||
b.attendanceIsCounted.setText(if (attendance.isCounted) R.string.yes else R.string.no)
|
b.attendanceIsCounted.setText(if (attendance.isCounted) R.string.yes else R.string.no)
|
||||||
|
|
||||||
|
attendance.teacherName?.let { name ->
|
||||||
|
BetterLink.attach(
|
||||||
|
b.teacherName,
|
||||||
|
teachers = mapOf(attendance.teacherId to name),
|
||||||
|
onActionSelected = dialog::dismiss
|
||||||
|
)
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import pl.szczodrzynski.edziennik.R
|
|||||||
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
import pl.szczodrzynski.edziennik.data.api.LOGIN_TYPE_MOBIDZIENNIK
|
||||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||||
import pl.szczodrzynski.edziennik.data.db.full.NoticeFull
|
import pl.szczodrzynski.edziennik.data.db.full.NoticeFull
|
||||||
|
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||||
import pl.szczodrzynski.edziennik.utils.Utils.bs
|
import pl.szczodrzynski.edziennik.utils.Utils.bs
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
@ -83,6 +84,14 @@ class NoticesAdapter//getting the context and product list with constructor
|
|||||||
} else {
|
} else {
|
||||||
holder.noticesItemReason.background = null
|
holder.noticesItemReason.background = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BetterLink.attach(holder.noticesItemReason)
|
||||||
|
|
||||||
|
notice.teacherName?.let { name ->
|
||||||
|
BetterLink.attach(holder.noticesItemTeacherName, teachers = mapOf(
|
||||||
|
notice.teacherId to name
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
|
@ -345,6 +345,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
|||||||
b.recipients.setAdapter(adapter)
|
b.recipients.setAdapter(adapter)
|
||||||
|
|
||||||
handleReplyMessage()
|
handleReplyMessage()
|
||||||
|
handleMailToIntent()
|
||||||
}}
|
}}
|
||||||
|
|
||||||
private fun handleReplyMessage() { launch {
|
private fun handleReplyMessage() { launch {
|
||||||
@ -402,6 +403,22 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
private fun handleMailToIntent() {
|
||||||
|
val teacherId = arguments?.getLong("messageRecipientId")
|
||||||
|
if (teacherId == 0L)
|
||||||
|
return
|
||||||
|
|
||||||
|
val chipList = mutableListOf<ChipInfo>()
|
||||||
|
teachers.firstOrNull { it.id == teacherId }?.let { teacher ->
|
||||||
|
teacher.image = getProfileImage(48, 24, 16, 12, 1, teacher.fullName)
|
||||||
|
chipList += ChipInfo(teacher.fullName, teacher)
|
||||||
|
}
|
||||||
|
b.recipients.addTextWithChips(chipList)
|
||||||
|
|
||||||
|
val subject = arguments?.getString("messageSubject")
|
||||||
|
b.subject.setText(subject ?: return)
|
||||||
|
}
|
||||||
|
|
||||||
private fun sendMessage() {
|
private fun sendMessage() {
|
||||||
b.recipientsLayout.error = null
|
b.recipientsLayout.error = null
|
||||||
b.subjectLayout.error = null
|
b.subjectLayout.error = null
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
package pl.szczodrzynski.edziennik.utils
|
package pl.szczodrzynski.edziennik.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.text.Spannable
|
import android.text.Spannable
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
@ -19,141 +21,268 @@ import android.view.ViewGroup
|
|||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.view.menu.MenuBuilder
|
import androidx.appcompat.view.menu.MenuBuilder
|
||||||
import androidx.appcompat.view.menu.MenuPopupHelper
|
import androidx.appcompat.view.menu.MenuPopupHelper
|
||||||
import pl.szczodrzynski.edziennik.Intent
|
import androidx.core.widget.addTextChangedListener
|
||||||
import pl.szczodrzynski.edziennik.copyToClipboard
|
import pl.szczodrzynski.edziennik.*
|
||||||
import pl.szczodrzynski.edziennik.data.api.Regexes
|
import pl.szczodrzynski.edziennik.data.api.Regexes
|
||||||
import pl.szczodrzynski.edziennik.get
|
|
||||||
import pl.szczodrzynski.edziennik.getTextPosition
|
|
||||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
object BetterLink {
|
object BetterLink {
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
/**
|
||||||
fun attach(textView: TextView, onActionSelected: (() -> Unit)? = null) {
|
* Used in conjunction with the item's ID to execute the
|
||||||
textView.autoLinkMask = Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES
|
* [attach]'s onActionSelected listener when the item is
|
||||||
BetterLinkMovementMethod.linkify(textView.autoLinkMask, textView).setOnLinkClickListener { v, span: BetterLinkMovementMethod.ClickableSpanWithText ->
|
* clicked.
|
||||||
val url = span.text()
|
*/
|
||||||
val c = v.context
|
private const val FLAG_ACTION = 0x8000
|
||||||
|
|
||||||
val s = v.text as Spanned
|
private fun MenuBuilder.setTitle(title: CharSequence): MenuBuilder {
|
||||||
val start = s.getSpanStart(span.span())
|
this::class.java.getDeclaredMethod("setHeaderTitleInt", CharSequence::class.java).let {
|
||||||
val end = s.getSpanEnd(span.span())
|
it.isAccessible = true
|
||||||
|
it.invoke(this, title)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
val parent = v.rootView.findViewById<ViewGroup>(android.R.id.content)
|
private fun MenuItem.addListener(listener: (item: MenuItem) -> Boolean): MenuItem {
|
||||||
val parentLocation = intArrayOf(0, 0)
|
this::class.java.getDeclaredField("mClickListener").let {
|
||||||
parent.getLocationOnScreen(parentLocation)
|
it.isAccessible = true
|
||||||
|
val oldListener = it.get(this) as? MenuItem.OnMenuItemClickListener
|
||||||
val rect = textView.getTextPosition(start..end)
|
it.set(this, object : MenuItem.OnMenuItemClickListener {
|
||||||
|
override fun onMenuItemClick(item: MenuItem): Boolean {
|
||||||
val view = View(c)
|
oldListener?.onMenuItemClick(item)
|
||||||
view.layoutParams = ViewGroup.LayoutParams(rect.width(), rect.height())
|
return listener(item)
|
||||||
view.setBackgroundColor(Color.TRANSPARENT)
|
|
||||||
|
|
||||||
parent.addView(view)
|
|
||||||
|
|
||||||
view.x = rect.left.toFloat() - parentLocation[0]
|
|
||||||
view.y = rect.top.toFloat() - parentLocation[1]
|
|
||||||
|
|
||||||
val menu = MenuBuilder(c)
|
|
||||||
val helper = MenuPopupHelper(c, menu, view)
|
|
||||||
val popup = helper.popup
|
|
||||||
|
|
||||||
var menuTitle = url.substringAfter(":")
|
|
||||||
var date: Date? = null
|
|
||||||
|
|
||||||
var urlItem: MenuItem? = null
|
|
||||||
var createEventItem: MenuItem? = null
|
|
||||||
//var goToTimetableItem: MenuItem? = null // TODO 2020-03-19: implement this
|
|
||||||
var mailItem: MenuItem? = null
|
|
||||||
var copyItem: MenuItem? = null
|
|
||||||
|
|
||||||
when {
|
|
||||||
url.startsWith("mailto:") -> {
|
|
||||||
mailItem = menu.add(1, 20, 2, "Napisz e-mail")
|
|
||||||
}
|
}
|
||||||
url.startsWith("dateYmd:") -> {
|
})
|
||||||
createEventItem = menu.add(1, 10, 2, "Utwórz wydarzenie")
|
}
|
||||||
//goToTimetableItem = menu.add(1, 11, 3, "Idź do planu lekcji")
|
return this
|
||||||
date = parseDateYmd(menuTitle)
|
}
|
||||||
}
|
|
||||||
url.startsWith("dateDmy:") -> {
|
|
||||||
createEventItem = menu.add(1, 10, 2, "Utwórz wydarzenie")
|
|
||||||
//goToTimetableItem = menu.add(1, 11, 3, "Idź do planu lekcji")
|
|
||||||
date = parseDateDmy(menuTitle)
|
|
||||||
}
|
|
||||||
url.startsWith("dateAbs:") -> {
|
|
||||||
createEventItem = menu.add(1, 10, 2, "Utwórz wydarzenie")
|
|
||||||
//goToTimetableItem = menu.add(1, 11, 3, "Idź do planu lekcji")
|
|
||||||
date = parseDateAbs(menuTitle)
|
|
||||||
}
|
|
||||||
url.startsWith("dateRel:") -> {
|
|
||||||
createEventItem = menu.add(1, 10, 2, "Utwórz wydarzenie")
|
|
||||||
//goToTimetableItem = menu.add(1, 11, 3, "Idź do planu lekcji")
|
|
||||||
date = parseDateRel(menuTitle)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
urlItem = menu.add(1, 1, 2, "Otwórz w przeglądarce")
|
|
||||||
menuTitle = url
|
|
||||||
}
|
|
||||||
}
|
|
||||||
copyItem = menu.add(1, 1000, 1000, "Kopiuj tekst")
|
|
||||||
|
|
||||||
helper.setOnDismissListener { parent.removeView(view) }
|
private fun createUrlItems(menu: MenuBuilder, context: Context, url: String) {
|
||||||
|
menu.setTitle(url)
|
||||||
|
menu.add(
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
2,
|
||||||
|
"Otwórz w przeglądarce"
|
||||||
|
).setOnMenuItemClickListener {
|
||||||
|
Utils.openUrl(context, url)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
urlItem?.setOnMenuItemClickListener { Utils.openUrl(c, url); true }
|
private fun createMailtoItems(menu: MenuBuilder, context: Context, url: String) {
|
||||||
mailItem?.setOnMenuItemClickListener { Utils.openUrl(c, url); true }
|
menu.add(
|
||||||
copyItem?.setOnMenuItemClickListener { menuTitle.copyToClipboard(c); true }
|
1,
|
||||||
createEventItem?.setOnMenuItemClickListener {
|
3,
|
||||||
onActionSelected?.invoke()
|
3,
|
||||||
val intent = Intent(
|
"Napisz e-mail"
|
||||||
android.content.Intent.ACTION_MAIN,
|
).setOnMenuItemClickListener {
|
||||||
"action" to "createManualEvent",
|
Utils.openUrl(context, url)
|
||||||
"eventDate" to date?.stringY_m_d
|
true
|
||||||
)
|
}
|
||||||
c.sendBroadcast(intent)
|
}
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
menu::class.java.getDeclaredMethod("setHeaderTitleInt", CharSequence::class.java).let {
|
private fun createDateItems(menu: MenuBuilder, context: Context, date: Date?) {
|
||||||
it.isAccessible = true
|
date ?: return
|
||||||
it.invoke(menu, menuTitle)
|
menu.setTitle(date.formattedString)
|
||||||
}
|
menu.add(
|
||||||
popup::class.java.getDeclaredField("mShowTitle").let {
|
1,
|
||||||
it.isAccessible = true
|
4 or FLAG_ACTION,
|
||||||
it.set(popup, true)
|
4,
|
||||||
}
|
"Utwórz wydarzenie"
|
||||||
helper::class.java.getDeclaredMethod("showPopup", Int::class.java, Int::class.java, Boolean::class.java, Boolean::class.java).let {
|
).setOnMenuItemClickListener {
|
||||||
it.isAccessible = true
|
val intent = Intent(
|
||||||
it.invoke(helper, 0, 0, false, true)
|
Intent.ACTION_MAIN,
|
||||||
}
|
"action" to "createManualEvent",
|
||||||
|
"eventDate" to date.stringY_m_d
|
||||||
|
)
|
||||||
|
context.sendBroadcast(intent)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createTeacherItems(menu: MenuBuilder, context: Context, teacherId: Long, fullName: String) {
|
||||||
|
menu.setTitle(fullName)
|
||||||
|
menu.add(
|
||||||
|
1,
|
||||||
|
5 or FLAG_ACTION,
|
||||||
|
5,
|
||||||
|
"Napisz wiadomość"
|
||||||
|
).setOnMenuItemClickListener {
|
||||||
|
val intent = Intent(
|
||||||
|
Intent.ACTION_MAIN,
|
||||||
|
"fragmentId" to MainActivity.TARGET_MESSAGES_COMPOSE,
|
||||||
|
"messageRecipientId" to teacherId
|
||||||
|
)
|
||||||
|
context.sendBroadcast(intent)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onClickListener(
|
||||||
|
view: TextView,
|
||||||
|
span: BetterLinkMovementMethod.ClickableSpanWithText,
|
||||||
|
onActionSelected: (() -> Unit)?
|
||||||
|
): Boolean {
|
||||||
|
val context = view.context
|
||||||
|
|
||||||
|
val spanned = view.text as Spanned
|
||||||
|
val start = spanned.getSpanStart(span.span())
|
||||||
|
val end = spanned.getSpanEnd(span.span())
|
||||||
|
|
||||||
|
val parent = view.rootView.findViewById<ViewGroup>(android.R.id.content)
|
||||||
|
val parentLocation = intArrayOf(0, 0)
|
||||||
|
parent.getLocationOnScreen(parentLocation)
|
||||||
|
|
||||||
|
val rect = view.getTextPosition(start..end)
|
||||||
|
|
||||||
|
val popupView = View(context)
|
||||||
|
popupView.layoutParams = ViewGroup.LayoutParams(rect.width(), rect.height())
|
||||||
|
popupView.setBackgroundColor(Color.TRANSPARENT)
|
||||||
|
|
||||||
|
parent.addView(popupView)
|
||||||
|
|
||||||
|
popupView.x = rect.left.toFloat() - parentLocation[0]
|
||||||
|
popupView.y = rect.top.toFloat() - parentLocation[1]
|
||||||
|
|
||||||
|
val menu = MenuBuilder(context)
|
||||||
|
val helper = MenuPopupHelper(context, menu, popupView)
|
||||||
|
val popup = helper.popup
|
||||||
|
|
||||||
|
val spanUrl = span.text()
|
||||||
|
val spanParameter = spanUrl.substringAfter(":")
|
||||||
|
val spanText = spanned.substring(start, end)
|
||||||
|
|
||||||
|
//goToTimetableItem = menu.add(1, 11, 3, "Idź do planu lekcji")
|
||||||
|
|
||||||
|
// create appropriate items for spans
|
||||||
|
when {
|
||||||
|
spanUrl.startsWith("mailto:") -> createMailtoItems(menu, context, spanUrl)
|
||||||
|
spanUrl.startsWith("dateYmd:") -> createDateItems(menu, context, parseDateYmd(spanParameter))
|
||||||
|
spanUrl.startsWith("dateDmy:") -> createDateItems(menu, context, parseDateDmy(spanParameter))
|
||||||
|
spanUrl.startsWith("dateAbs:") -> createDateItems(menu, context, parseDateAbs(spanParameter))
|
||||||
|
spanUrl.startsWith("dateRel:") -> createDateItems(menu, context, parseDateRel(spanParameter))
|
||||||
|
spanUrl.startsWith("teacher:") -> createTeacherItems(
|
||||||
|
menu,
|
||||||
|
context,
|
||||||
|
teacherId = spanParameter.toLongOrNull() ?: -1,
|
||||||
|
fullName = spanText
|
||||||
|
)
|
||||||
|
else -> createUrlItems(menu, context, spanUrl)
|
||||||
|
}
|
||||||
|
menu.add(1, 1000, 1000, "Kopiuj tekst").setOnMenuItemClickListener {
|
||||||
|
spanParameter.copyToClipboard(context)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
val spanned = textView.text as? Spannable ?: {
|
helper.setOnDismissListener { parent.removeView(popupView) }
|
||||||
SpannableString(textView.text)
|
|
||||||
}()
|
menu.visibleItems.forEach { item ->
|
||||||
|
if ((item.itemId and FLAG_ACTION) != FLAG_ACTION)
|
||||||
|
return@forEach
|
||||||
|
item.addListener {
|
||||||
|
onActionSelected?.invoke()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
popup::class.java.getDeclaredField("mShowTitle").let {
|
||||||
|
it.isAccessible = true
|
||||||
|
it.set(popup, true)
|
||||||
|
}
|
||||||
|
helper::class.java.getDeclaredMethod(
|
||||||
|
"showPopup",
|
||||||
|
Int::class.java,
|
||||||
|
Int::class.java,
|
||||||
|
Boolean::class.java,
|
||||||
|
Boolean::class.java
|
||||||
|
).let {
|
||||||
|
it.isAccessible = true
|
||||||
|
it.invoke(helper, 0, 0, false, true)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun attach(
|
||||||
|
textView: TextView,
|
||||||
|
teachers: Map<Long, String>? = null,
|
||||||
|
onActionSelected: (() -> Unit)? = null
|
||||||
|
) {
|
||||||
|
textView.autoLinkMask = Linkify.WEB_URLS or Linkify.EMAIL_ADDRESSES
|
||||||
|
|
||||||
|
BetterLinkMovementMethod
|
||||||
|
.linkify(textView.autoLinkMask, textView)
|
||||||
|
.setOnLinkClickListener { view, span ->
|
||||||
|
onClickListener(view, span, onActionSelected)
|
||||||
|
}
|
||||||
|
|
||||||
|
textView.addTextChangedListener {
|
||||||
|
attachSpan(textView, teachers)
|
||||||
|
}
|
||||||
|
|
||||||
|
attachSpan(textView, teachers)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun attachSpan(
|
||||||
|
textView: TextView,
|
||||||
|
teachers: Map<Long, String>? = null
|
||||||
|
) {
|
||||||
|
val spanned = textView.text as? Spannable ?: SpannableString(textView.text)
|
||||||
|
|
||||||
|
teachers?.forEach { (id, fullName) ->
|
||||||
|
val index = textView.text.indexOf(fullName)
|
||||||
|
if (index == -1)
|
||||||
|
return@forEach
|
||||||
|
val span = URLSpan("teacher:$id")
|
||||||
|
spanned.setSpan(
|
||||||
|
span,
|
||||||
|
index,
|
||||||
|
index + fullName.length,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Regexes.LINKIFY_DATE_YMD.findAll(textView.text).forEach { match ->
|
Regexes.LINKIFY_DATE_YMD.findAll(textView.text).forEach { match ->
|
||||||
val span = URLSpan("dateYmd:" + match.value)
|
val span = URLSpan("dateYmd:" + match.value)
|
||||||
spanned.setSpan(span, match.range.first, match.range.last + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spanned.setSpan(
|
||||||
|
span,
|
||||||
|
match.range.first,
|
||||||
|
match.range.last + 1,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Regexes.LINKIFY_DATE_DMY.findAll(textView.text).forEach { match ->
|
Regexes.LINKIFY_DATE_DMY.findAll(textView.text).forEach { match ->
|
||||||
val span = URLSpan("dateDmy:" + match.value)
|
val span = URLSpan("dateDmy:" + match.value)
|
||||||
spanned.setSpan(span, match.range.first, match.range.last + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spanned.setSpan(
|
||||||
|
span,
|
||||||
|
match.range.first,
|
||||||
|
match.range.last + 1,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Regexes.LINKIFY_DATE_ABSOLUTE.findAll(textView.text).forEach { match ->
|
Regexes.LINKIFY_DATE_ABSOLUTE.findAll(textView.text).forEach { match ->
|
||||||
val span = URLSpan("dateAbs:" + match.value)
|
val span = URLSpan("dateAbs:" + match.value)
|
||||||
spanned.setSpan(span, match.range.first, match.range.last + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spanned.setSpan(
|
||||||
|
span,
|
||||||
|
match.range.first,
|
||||||
|
match.range.last + 1,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Regexes.LINKIFY_DATE_RELATIVE.findAll(textView.text).forEach { match ->
|
Regexes.LINKIFY_DATE_RELATIVE.findAll(textView.text).forEach { match ->
|
||||||
val span = URLSpan("dateRel:" + match.value)
|
val span = URLSpan("dateRel:" + match.value)
|
||||||
spanned.setSpan(span, match.range.first, match.range.last + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
spanned.setSpan(
|
||||||
|
span,
|
||||||
|
match.range.first,
|
||||||
|
match.range.last + 1,
|
||||||
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
//Linkify.addLinks(textView, LINKIFY_DATE_ABSOLUTE.toPattern(), "dateAbs:")
|
|
||||||
//Linkify.addLinks(textView, LINKIFY_DATE_RELATIVE.toPattern(), "dateRel:")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val monthNames = listOf("sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paź", "lis", "gru")
|
private val monthNames =
|
||||||
|
listOf("sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paź", "lis", "gru")
|
||||||
|
|
||||||
private fun parseDateYmd(text: String): Date? {
|
private fun parseDateYmd(text: String): Date? {
|
||||||
return Regexes.LINKIFY_DATE_YMD.find(text)?.let {
|
return Regexes.LINKIFY_DATE_YMD.find(text)?.let {
|
||||||
@ -163,6 +292,7 @@ object BetterLink {
|
|||||||
Date(year, month, day)
|
Date(year, month, day)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseDateDmy(text: String): Date? {
|
private fun parseDateDmy(text: String): Date? {
|
||||||
return Regexes.LINKIFY_DATE_DMY.find(text)?.let {
|
return Regexes.LINKIFY_DATE_DMY.find(text)?.let {
|
||||||
val day = it[1].toIntOrNull() ?: 1
|
val day = it[1].toIntOrNull() ?: 1
|
||||||
@ -194,7 +324,7 @@ object BetterLink {
|
|||||||
else -> 1
|
else -> 1
|
||||||
}
|
}
|
||||||
|
|
||||||
date.stepForward(0, 0, amount*unitInDays)
|
date.stepForward(0, 0, amount * unitInDays)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
android:textAppearance="@style/NavView.TextView.Helper" />
|
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/teacherName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="0dp"
|
||||||
|
@ -112,6 +112,7 @@
|
|||||||
android:text="@string/dialog_event_details_teacher"
|
android:text="@string/dialog_event_details_teacher"
|
||||||
android:visibility="@{event.teacherName != null ? View.VISIBLE : View.GONE}"/>
|
android:visibility="@{event.teacherName != null ? View.VISIBLE : View.GONE}"/>
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/teacherName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@{event.teacherName}"
|
android:text="@{event.teacherName}"
|
||||||
|
@ -121,6 +121,7 @@
|
|||||||
android:textAppearance="@style/NavView.TextView.Helper" />
|
android:textAppearance="@style/NavView.TextView.Helper" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/teacherName"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="0dp"
|
android:layout_marginTop="0dp"
|
||||||
|
@ -176,6 +176,7 @@
|
|||||||
android:textAppearance="@style/NavView.TextView.Helper"
|
android:textAppearance="@style/NavView.TextView.Helper"
|
||||||
android:text="@string/dialog_lesson_details_teacher" />
|
android:text="@string/dialog_lesson_details_teacher" />
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/oldTeacherNameView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/NavView.TextView.Helper"
|
android:textAppearance="@style/NavView.TextView.Helper"
|
||||||
@ -186,6 +187,7 @@
|
|||||||
app:strikeThrough="@{true}"
|
app:strikeThrough="@{true}"
|
||||||
tools:text="Janósz Kowalski" />
|
tools:text="Janósz Kowalski" />
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/teacherNameView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@{teacherName}"
|
android:text="@{teacherName}"
|
||||||
|
@ -856,7 +856,7 @@
|
|||||||
<string name="settings_about_licenses_text">Open-Source-Lizenzen</string>
|
<string name="settings_about_licenses_text">Open-Source-Lizenzen</string>
|
||||||
<string name="settings_about_privacy_policy_text">Datenschutzrichtlinie</string>
|
<string name="settings_about_privacy_policy_text">Datenschutzrichtlinie</string>
|
||||||
<string name="settings_card_register_title">E-Klassenbuch</string>
|
<string name="settings_card_register_title">E-Klassenbuch</string>
|
||||||
<string name="settings_about_title_subtext">© Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 - Februar 2021</string>
|
<string name="settings_about_title_subtext">© Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 - April 2021</string>
|
||||||
<string name="settings_about_update_subtext">Klicken Sie hier, um nach Aktualisierungen zu suchen</string>
|
<string name="settings_about_update_subtext">Klicken Sie hier, um nach Aktualisierungen zu suchen</string>
|
||||||
<string name="settings_about_update_text">Aktualisierung</string>
|
<string name="settings_about_update_text">Aktualisierung</string>
|
||||||
<string name="settings_about_version_text">Version</string>
|
<string name="settings_about_version_text">Version</string>
|
||||||
|
@ -858,7 +858,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_card_register_title">E-register</string>
|
<string name="settings_card_register_title">E-register</string>
|
||||||
<string name="settings_about_title_subtext">© Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 - February 2021</string>
|
<string name="settings_about_title_subtext">© Kuba Szczodrzyński && Kacper Ziubryniewicz\nSeptember 2018 - April 2021</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>
|
||||||
|
@ -921,7 +921,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_card_register_title">E-dziennik</string>
|
<string name="settings_card_register_title">E-dziennik</string>
|
||||||
<string name="settings_about_title_subtext">© Kuba Szczodrzyński && Kacper Ziubryniewicz\nwrzesień 2018 - luty 2021</string>
|
<string name="settings_about_title_subtext">© Kuba Szczodrzyński && Kacper Ziubryniewicz\nwrzesień 2018 - kwiecień 2021</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>
|
||||||
|
@ -5,8 +5,8 @@ buildscript {
|
|||||||
kotlin_version = '1.4.31'
|
kotlin_version = '1.4.31'
|
||||||
|
|
||||||
release = [
|
release = [
|
||||||
versionName: "4.7",
|
versionName: "4.7.1",
|
||||||
versionCode: 4070099
|
versionCode: 4070199
|
||||||
]
|
]
|
||||||
|
|
||||||
setup = [
|
setup = [
|
||||||
|
Reference in New Issue
Block a user