mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-02-21 14:04:45 +01:00
[UI] Migrate to base fragment classes, restructure base modules (#206)
* Replace android:visibility with android:isVisible * Move base dialogs and views to .ui.base * Move uncategorized classes to ui.main * Fix view classes in XML * Add BaseFragment, use for LazyFragment * Migrate fragments to BaseFragment * Move activity setup from BaseFragment, recreate Job on attach * Move BaseFragment initialization to onResume * Add base PagerFragment, add TemplateFragment to drawer * Support swipe-to-refresh in base fragments * Remove SwipeRefreshLayout split implementation * Rename onViewCreated to onViewReady * Remove LazyFragment * Save page selection in PagerFragment, migrate AttendanceFragment * Migrate fragments to PagerFragment * Migrate contributors to a fragment * Migrate TimetableFragment to PagerFragment * Fix disabling SwipeToRefresh on page scroll * Fix crash in CrashActivity
This commit is contained in:
parent
f795412551
commit
10043cc62c
1
.idea/codeStyles/Project.xml
generated
1
.idea/codeStyles/Project.xml
generated
@ -143,6 +143,7 @@
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
|
||||
<option name="PARAMETER_ANNOTATION_WRAP" value="2" />
|
||||
<option name="ENUM_CONSTANTS_WRAP" value="2" />
|
||||
</codeStyleSettings>
|
||||
|
@ -126,7 +126,7 @@
|
||||
/ ____ \ (__| |_| |\ V /| | |_| | __/\__ \
|
||||
/_/ \_\___|\__|_| \_/ |_|\__|_|\___||___/
|
||||
-->
|
||||
<activity android:name=".ui.base.CrashActivity"
|
||||
<activity android:name=".ui.main.CrashActivity"
|
||||
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||
android:process=":error_activity"
|
||||
android:exported="false"
|
||||
@ -163,8 +163,7 @@
|
||||
android:configChanges="orientation|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.MaterialComponents.Light.DarkActionBar" />
|
||||
<activity android:name=".ui.base.BuildInvalidActivity" android:exported="false" />
|
||||
<activity android:name=".ui.settings.contributors.ContributorsActivity" android:exported="false" />
|
||||
<activity android:name=".ui.main.BuildInvalidActivity" android:exported="false" />
|
||||
|
||||
<!-- _____ _
|
||||
| __ \ (_)
|
||||
|
@ -54,7 +54,7 @@ import pl.szczodrzynski.edziennik.data.db.AppDb
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.enums.LoginType
|
||||
import pl.szczodrzynski.edziennik.network.SSLProviderInstaller
|
||||
import pl.szczodrzynski.edziennik.ui.base.CrashActivity
|
||||
import pl.szczodrzynski.edziennik.ui.main.CrashActivity
|
||||
import pl.szczodrzynski.edziennik.utils.PermissionChecker
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import timber.log.Timber
|
||||
|
@ -19,6 +19,7 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.danimahardhika.cafebar.CafeBar
|
||||
import com.danimahardhika.cafebar.CafeBarTheme
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@ -49,7 +50,7 @@ import pl.szczodrzynski.edziennik.core.work.AppManagerDetectedEvent
|
||||
import pl.szczodrzynski.edziennik.core.work.SyncWorker
|
||||
import pl.szczodrzynski.edziennik.core.work.UpdateStateEvent
|
||||
import pl.szczodrzynski.edziennik.core.work.UpdateWorker
|
||||
import pl.szczodrzynski.edziennik.ui.base.MainSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.main.MainSnackbar
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTargetLocation
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ChangelogDialog
|
||||
@ -59,8 +60,8 @@ import pl.szczodrzynski.edziennik.ui.dialogs.sync.ServerMessageDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.SyncViewListDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.UpdateAvailableDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.sync.UpdateProgressDialog
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.main.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginActivity
|
||||
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
||||
@ -76,7 +77,6 @@ import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import pl.szczodrzynski.navlib.drawer.NavDrawer
|
||||
import pl.szczodrzynski.navlib.drawer.items.DrawerPrimaryItem
|
||||
import timber.log.Timber
|
||||
import java.io.IOException
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -97,7 +97,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
val errorSnackbar: ErrorSnackbar by lazy { ErrorSnackbar(this) }
|
||||
val requestHandler by lazy { MainActivityRequestHandler(this) }
|
||||
|
||||
val swipeRefreshLayout: SwipeRefreshLayoutNoTouch by lazy { b.swipeRefreshLayout }
|
||||
val swipeRefreshLayout: SwipeRefreshLayout by lazy { b.swipeRefreshLayout }
|
||||
|
||||
var onBeforeNavigate: (() -> Boolean)? = null
|
||||
private var pausedNavigationData: PausedNavigationData? = null
|
||||
@ -264,9 +264,8 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
drawer.setUnreadCounterList(unreadCounters)
|
||||
}
|
||||
|
||||
b.swipeRefreshLayout.isEnabled = true
|
||||
b.swipeRefreshLayout.setOnRefreshListener { launch { syncCurrentFeature() } }
|
||||
b.swipeRefreshLayout.setColorSchemeResources(
|
||||
swipeRefreshLayout.setOnRefreshListener { launch { syncCurrentFeature() } }
|
||||
swipeRefreshLayout.setColorSchemeResources(
|
||||
R.color.md_blue_500,
|
||||
R.color.md_amber_500,
|
||||
R.color.md_green_500
|
||||
@ -939,6 +938,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope {
|
||||
val arguments = args
|
||||
?: navBackStack.firstOrNull { it.first == navTarget }?.second
|
||||
?: Bundle()
|
||||
swipeRefreshLayout.isEnabled = false
|
||||
bottomSheet.close()
|
||||
bottomSheet.removeAllContextual()
|
||||
bottomSheet.toggleGroupEnabled = false
|
||||
|
@ -34,7 +34,7 @@ import pl.szczodrzynski.edziennik.ext.md5
|
||||
import pl.szczodrzynski.edziennik.ext.resolveAttr
|
||||
import pl.szczodrzynski.edziennik.ext.resolveColor
|
||||
import pl.szczodrzynski.edziennik.ext.toJsonObject
|
||||
import pl.szczodrzynski.edziennik.ui.base.BuildInvalidActivity
|
||||
import pl.szczodrzynski.edziennik.ui.main.BuildInvalidActivity
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import timber.log.Timber
|
||||
import java.time.Instant
|
||||
|
@ -69,6 +69,14 @@ class FirebaseManager(val app: App) {
|
||||
)
|
||||
|
||||
fun initializeApps() {
|
||||
try {
|
||||
// skip Firebase setup if the default app is not initialized
|
||||
// (e.g. in the crash process)
|
||||
FirebaseApp.getInstance()
|
||||
} catch (e: IllegalStateException) {
|
||||
return
|
||||
}
|
||||
|
||||
FirebaseInstanceId.getInstance().instanceId.addOnSuccessListener { result ->
|
||||
val token = result.token
|
||||
Timber.i("Got App token: $token")
|
||||
|
@ -28,8 +28,8 @@ import pl.szczodrzynski.edziennik.ext.keys
|
||||
import pl.szczodrzynski.edziennik.ext.md5
|
||||
import pl.szczodrzynski.edziennik.ext.toApiError
|
||||
import pl.szczodrzynski.edziennik.ext.toErrorCode
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.main.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginInfo
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
@ -30,7 +30,9 @@ import pl.szczodrzynski.edziennik.ui.notes.NotesFragment
|
||||
import pl.szczodrzynski.edziennik.ui.notifications.NotificationsListFragment
|
||||
import pl.szczodrzynski.edziennik.ui.settings.ProfileManagerFragment
|
||||
import pl.szczodrzynski.edziennik.ui.settings.SettingsFragment
|
||||
import pl.szczodrzynski.edziennik.ui.settings.contributors.ContributorsFragment
|
||||
import pl.szczodrzynski.edziennik.ui.teachers.TeachersListFragment
|
||||
import pl.szczodrzynski.edziennik.ui.template.TemplateFragment
|
||||
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
|
||||
import pl.szczodrzynski.edziennik.ui.webpush.WebPushFragment
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
@ -177,6 +179,15 @@ enum class NavTarget(
|
||||
popTo = HOME,
|
||||
devModeOnly = true,
|
||||
),
|
||||
TEMPLATE(
|
||||
id = 1001,
|
||||
fragmentClass = TemplateFragment::class.java,
|
||||
location = NavTargetLocation.DRAWER_BOTTOM,
|
||||
nameRes = R.string.menu_template,
|
||||
icon = CommunityMaterial.Icon.cmd_code_braces,
|
||||
popTo = HOME,
|
||||
devModeOnly = true,
|
||||
),
|
||||
PROFILE_ADD(
|
||||
id = 200,
|
||||
fragmentClass = null,
|
||||
@ -243,6 +254,11 @@ enum class NavTarget(
|
||||
id = 140,
|
||||
fragmentClass = WebPushFragment::class.java,
|
||||
nameRes = R.string.menu_web_push,
|
||||
),
|
||||
CONTRIBUTORS(
|
||||
id = 150,
|
||||
fragmentClass = ContributorsFragment::class.java,
|
||||
nameRes = R.string.contributors,
|
||||
);
|
||||
|
||||
companion object {
|
||||
|
@ -31,34 +31,33 @@ fun Bundle?.getIntOrNull(key: String): Int? {
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> Bundle?.get(key: String): T? {
|
||||
return this?.get(key) as? T?
|
||||
operator fun Bundle.set(key: String, value: Any) = when (value) {
|
||||
is String -> putString(key, value as String?)
|
||||
is Char -> putChar(key, value)
|
||||
is Int -> putInt(key, value)
|
||||
is Long -> putLong(key, value)
|
||||
is Float -> putFloat(key, value)
|
||||
is Short -> putShort(key, value)
|
||||
is Double -> putDouble(key, value)
|
||||
is Boolean -> putBoolean(key, value)
|
||||
is Bundle -> putBundle(key, value)
|
||||
is Enum<*> -> putEnum(key, value)
|
||||
is Array<*> -> putParcelableArray(key, value as Array<out Parcelable>)
|
||||
is Parcelable -> putParcelable(key, value)
|
||||
is Serializable -> putSerializable(key, value)
|
||||
else -> throw IllegalArgumentException("Couldn't serialize $key = $value")
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun Bundle(vararg properties: Pair<String, Any?>): Bundle {
|
||||
return Bundle().apply {
|
||||
for (property in properties) {
|
||||
val (key, value) = property
|
||||
when (value) {
|
||||
is String -> putString(key, value as String?)
|
||||
is Char -> putChar(key, value)
|
||||
is Int -> putInt(key, value)
|
||||
is Long -> putLong(key, value)
|
||||
is Float -> putFloat(key, value)
|
||||
is Short -> putShort(key, value)
|
||||
is Double -> putDouble(key, value)
|
||||
is Boolean -> putBoolean(key, value)
|
||||
is Bundle -> putBundle(key, value)
|
||||
is Enum<*> -> putEnum(key, value)
|
||||
is Array<*> -> putParcelableArray(key, value as Array<out Parcelable>)
|
||||
is Parcelable -> putParcelable(key, value)
|
||||
is Serializable -> putSerializable(key, value)
|
||||
}
|
||||
}
|
||||
fun Bundle.putExtras(vararg properties: Pair<String, Any?>): Bundle {
|
||||
for (property in properties) {
|
||||
val (key, value) = property
|
||||
this[key] = value ?: continue
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun Bundle(vararg properties: Pair<String, Any?>) = Bundle().putExtras(*properties)
|
||||
|
||||
fun Intent(action: String? = null, vararg properties: Pair<String, Any?>): Intent {
|
||||
return Intent(action).putExtras(Bundle(*properties))
|
||||
}
|
||||
@ -68,7 +67,7 @@ fun Intent(packageContext: Context, cls: Class<*>, vararg properties: Pair<Strin
|
||||
}
|
||||
|
||||
fun Intent.putExtras(vararg properties: Pair<String, Any?>) = putExtras(Bundle(*properties))
|
||||
fun Bundle.putExtras(vararg properties: Pair<String, Any?>) = putAll(Bundle(*properties))
|
||||
|
||||
|
||||
fun Bundle.toJsonObject(): JsonObject {
|
||||
val json = JsonObject()
|
||||
|
@ -7,10 +7,11 @@ package pl.szczodrzynski.edziennik.ext
|
||||
import android.app.UiModeManager
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.getSystemService
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
|
||||
val Context.app
|
||||
val AppCompatActivity.app
|
||||
get() = applicationContext as App
|
||||
|
||||
val Context.isNightMode: Boolean
|
||||
|
@ -61,6 +61,12 @@ fun @receiver:AttrRes Int.resolveAttr(context: Context?): Int {
|
||||
}
|
||||
return typedValue.data
|
||||
}
|
||||
@StyleRes
|
||||
fun @receiver:AttrRes Int.resolveStyleAttr(context: Context?): Int {
|
||||
val typedValue = TypedValue()
|
||||
context?.theme?.resolveAttribute(this, typedValue, true)
|
||||
return typedValue.data
|
||||
}
|
||||
@Dimension
|
||||
fun @receiver:AttrRes Int.resolveDimenAttr(context: Context): Float {
|
||||
val typedValue = TypedValue()
|
||||
|
@ -13,7 +13,6 @@ import android.view.WindowManager
|
||||
import android.widget.*
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
||||
@ -152,16 +151,6 @@ inline fun ViewPager.addOnPageSelectedListener(crossinline block: (position: Int
|
||||
override fun onPageSelected(position: Int) { block(position) }
|
||||
})
|
||||
|
||||
val SwipeRefreshLayout.onScrollListener: RecyclerView.OnScrollListener
|
||||
get() = object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
if (recyclerView.canScrollVertically(-1))
|
||||
this@onScrollListener.isEnabled = false
|
||||
if (!recyclerView.canScrollVertically(-1) && newState == RecyclerView.SCROLL_STATE_IDLE)
|
||||
this@onScrollListener.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
fun View.removeFromParent() {
|
||||
(parent as? ViewGroup)?.removeView(this)
|
||||
}
|
||||
|
@ -8,135 +8,103 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.applandeo.materialcalendarview.EventDay
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.colorInt
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import eu.szkolny.font.SzkolnyFont
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaCalendarBinding
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentAgendaDefaultBinding
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.AgendaConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
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
|
||||
|
||||
class AgendaFragment : Fragment(), CoroutineScope {
|
||||
class AgendaFragment : BaseFragment<ViewDataBinding, MainActivity>(
|
||||
inflater = null,
|
||||
) {
|
||||
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: ViewDataBinding
|
||||
override fun inflate(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup?,
|
||||
attachToParent: Boolean,
|
||||
) = when (app.profile.config.ui.agendaViewType) {
|
||||
Profile.AGENDA_DEFAULT -> FragmentAgendaDefaultBinding.inflate(inflater, parent, false)
|
||||
Profile.AGENDA_CALENDAR -> FragmentAgendaCalendarBinding.inflate(inflater, parent, false)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private val app by lazy { activity.app }
|
||||
|
||||
private var job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
private var type: Int = Profile.AGENDA_DEFAULT
|
||||
override fun getFab() = R.string.add to CommunityMaterial.Icon3.cmd_plus
|
||||
override fun getMarkAsReadType() = MetadataType.EVENT
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_add_event)
|
||||
.withDescription(R.string.menu_add_event_desc)
|
||||
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
EventManualDialog(
|
||||
activity,
|
||||
app.profileId,
|
||||
defaultDate = AgendaFragmentDefault.selectedDate
|
||||
).show()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_agenda_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
AgendaConfigDialog(activity, true, null, null).show()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_agenda_change_view)
|
||||
.withIcon(
|
||||
if (app.profile.config.ui.agendaViewType == Profile.AGENDA_DEFAULT)
|
||||
CommunityMaterial.Icon.cmd_calendar_outline
|
||||
else
|
||||
CommunityMaterial.Icon2.cmd_format_list_bulleted_square
|
||||
)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
app.profile.config.ui.agendaViewType =
|
||||
if (app.profile.config.ui.agendaViewType == Profile.AGENDA_DEFAULT)
|
||||
Profile.AGENDA_CALENDAR
|
||||
else
|
||||
Profile.AGENDA_DEFAULT
|
||||
activity.reloadTarget()
|
||||
},
|
||||
)
|
||||
|
||||
private var agendaDefault: AgendaFragmentDefault? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
if (getActivity() == null || context == null) return null
|
||||
activity = getActivity() as MainActivity
|
||||
type = app.profile.config.ui.agendaViewType
|
||||
b = when (type) {
|
||||
Profile.AGENDA_DEFAULT -> FragmentAgendaDefaultBinding.inflate(inflater, container, false)
|
||||
Profile.AGENDA_CALENDAR -> FragmentAgendaCalendarBinding.inflate(inflater, container, false)
|
||||
else -> return null
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
when (app.profile.config.ui.agendaViewType) {
|
||||
Profile.AGENDA_DEFAULT -> createDefaultAgendaView(
|
||||
b as? FragmentAgendaDefaultBinding ?: return
|
||||
)
|
||||
Profile.AGENDA_CALENDAR -> createCalendarAgendaView(
|
||||
b as? FragmentAgendaCalendarBinding ?: return
|
||||
)
|
||||
}
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_add_event)
|
||||
.withDescription(R.string.menu_add_event_desc)
|
||||
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
EventManualDialog(
|
||||
activity,
|
||||
app.profileId,
|
||||
defaultDate = AgendaFragmentDefault.selectedDate
|
||||
).show()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_agenda_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
AgendaConfigDialog(activity, true, null, null).show()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_agenda_change_view)
|
||||
.withIcon(if (type == Profile.AGENDA_DEFAULT) CommunityMaterial.Icon.cmd_calendar_outline else CommunityMaterial.Icon2.cmd_format_list_bulleted_square)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
type =
|
||||
if (type == Profile.AGENDA_DEFAULT) Profile.AGENDA_CALENDAR else Profile.AGENDA_DEFAULT
|
||||
app.profile.config.ui.agendaViewType = type
|
||||
activity.reloadTarget()
|
||||
},
|
||||
BottomSheetSeparatorItem(true),
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_mark_as_read)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||
.withOnClickListener {
|
||||
launch {
|
||||
activity.bottomSheet.close()
|
||||
withContext(Dispatchers.Default) {
|
||||
App.db.metadataDao()
|
||||
.setAllSeen(app.profileId, MetadataType.EVENT, true)
|
||||
}
|
||||
Toast.makeText(
|
||||
activity,
|
||||
R.string.main_menu_mark_as_read_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
activity.navView.bottomBar.fabEnable = true
|
||||
activity.navView.bottomBar.fabExtendedText = getString(R.string.add)
|
||||
activity.navView.bottomBar.fabIcon = CommunityMaterial.Icon3.cmd_plus
|
||||
activity.navView.setFabOnClickListener {
|
||||
EventManualDialog(
|
||||
activity,
|
||||
app.profileId,
|
||||
defaultDate = AgendaFragmentDefault.selectedDate
|
||||
).show()
|
||||
}
|
||||
|
||||
activity.gainAttention()
|
||||
activity.gainAttentionFAB()
|
||||
|
||||
when (type) {
|
||||
Profile.AGENDA_DEFAULT -> createDefaultAgendaView()
|
||||
Profile.AGENDA_CALENDAR -> createCalendarAgendaView()
|
||||
}
|
||||
override suspend fun onFabClick() {
|
||||
EventManualDialog(
|
||||
activity,
|
||||
app.profileId,
|
||||
defaultDate = AgendaFragmentDefault.selectedDate
|
||||
).show()
|
||||
}
|
||||
|
||||
private suspend fun checkEventTypes() {
|
||||
@ -145,23 +113,25 @@ class AgendaFragment : Fragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
|
||||
private fun createDefaultAgendaView() { (b as? FragmentAgendaDefaultBinding)?.let { b -> launch {
|
||||
private suspend fun createDefaultAgendaView(b: FragmentAgendaDefaultBinding) {
|
||||
if (!isAdded)
|
||||
return@launch
|
||||
return
|
||||
checkEventTypes()
|
||||
delay(500)
|
||||
|
||||
agendaDefault = AgendaFragmentDefault(activity, app, b)
|
||||
agendaDefault?.initView(this@AgendaFragment)
|
||||
}}}
|
||||
}
|
||||
|
||||
private fun createCalendarAgendaView() { (b as? FragmentAgendaCalendarBinding)?.let { b -> launch {
|
||||
private suspend fun createCalendarAgendaView(b: FragmentAgendaCalendarBinding) {
|
||||
checkEventTypes()
|
||||
delay(300)
|
||||
|
||||
val dayList = mutableListOf<EventDay>()
|
||||
|
||||
val events = withContext(Dispatchers.Default) { app.db.eventDao().getAllNow(app.profileId) }
|
||||
val events = withContext(Dispatchers.IO) {
|
||||
app.db.eventDao().getAllNow(app.profileId)
|
||||
}
|
||||
val unreadEventDates = mutableSetOf<Int>()
|
||||
|
||||
events.forEach { event ->
|
||||
@ -189,5 +159,5 @@ class AgendaFragment : Fragment(), CoroutineScope {
|
||||
}}
|
||||
|
||||
b.progressBar.visibility = View.GONE
|
||||
}}}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import pl.szczodrzynski.edziennik.ui.agenda.lessonchanges.LessonChangesEventRend
|
||||
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceDialog
|
||||
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceEvent
|
||||
import pl.szczodrzynski.edziennik.ui.agenda.teacherabsence.TeacherAbsenceEventRenderer
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventListAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||
|
@ -7,7 +7,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonChangeListBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.timetable.LessonDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
|
||||
|
@ -7,7 +7,7 @@ import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogTeacherAbsenceListBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
|
||||
class TeacherAbsenceDialog(
|
||||
|
@ -51,7 +51,6 @@ public class AnnouncementsFragment extends Fragment {
|
||||
app = (App) activity.getApplication();
|
||||
// activity, context and profile is valid
|
||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_announcements, container, false);
|
||||
b.refreshLayout.setParent(activity.getSwipeRefreshLayout());
|
||||
return b.getRoot();
|
||||
}
|
||||
|
||||
@ -77,10 +76,6 @@ public class AnnouncementsFragment extends Fragment {
|
||||
})
|
||||
);
|
||||
|
||||
/*b.refreshLayout.setOnRefreshListener(() -> {
|
||||
activity.syncCurrentFeature(MainActivity.DRAWER_ITEM_ANNOUNCEMENTS, b.refreshLayout);
|
||||
});*/
|
||||
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
||||
|
||||
//RecyclerViewExpandableItemManager expMgr = new RecyclerViewExpandableItemManager(null);
|
||||
@ -90,18 +85,6 @@ public class AnnouncementsFragment extends Fragment {
|
||||
recyclerView.setLayoutManager(linearLayoutManager);
|
||||
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(view.getContext()));
|
||||
|
||||
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||
@Override
|
||||
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
|
||||
if (recyclerView.canScrollVertically(-1)) {
|
||||
b.refreshLayout.setEnabled(false);
|
||||
}
|
||||
if (!recyclerView.canScrollVertically(-1) && newState == SCROLL_STATE_IDLE) {
|
||||
b.refreshLayout.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.getDb().announcementDao().getAll(App.Companion.getProfileId()).observe(getViewLifecycleOwner(), announcements -> {
|
||||
if (app == null || activity == null || b == null || !isAdded())
|
||||
return;
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
||||
import pl.szczodrzynski.edziennik.databinding.AttendanceDetailsDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.setTintColor
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.notes.setupNotesButton
|
||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||
import pl.szczodrzynski.edziennik.core.manager.NoteManager
|
||||
|
@ -4,118 +4,59 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.attendance
|
||||
|
||||
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 com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.databinding.AttendanceFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.databinding.BasePagerFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.addOnPageSelectedListener
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.FragmentLazyPagerAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.PagerFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.AttendanceConfigDialog
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class AttendanceFragment : Fragment(), CoroutineScope {
|
||||
class AttendanceFragment : PagerFragment<BasePagerFragmentBinding, MainActivity>(
|
||||
inflater = BasePagerFragmentBinding::inflate,
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "AttendanceFragment"
|
||||
const val VIEW_SUMMARY = 0
|
||||
const val VIEW_DAYS = 1
|
||||
const val VIEW_MONTHS = 2
|
||||
const val VIEW_TYPES = 3
|
||||
const val VIEW_LIST = 4
|
||||
var pageSelection = 1
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: AttendanceFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = AttendanceFragmentBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_attendance_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener(View.OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
AttendanceConfigDialog(activity, true, null, null).show()
|
||||
}),
|
||||
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, MetadataType.ATTENDANCE, true) }
|
||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
)
|
||||
activity.gainAttention()
|
||||
|
||||
if (pageSelection == 1)
|
||||
pageSelection = app.profile.config.attendance.attendancePageSelection
|
||||
|
||||
val pagerAdapter = FragmentLazyPagerAdapter(
|
||||
parentFragmentManager,
|
||||
b.refreshLayout,
|
||||
listOf(
|
||||
AttendanceSummaryFragment() to getString(R.string.attendance_tab_summary),
|
||||
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_DAYS)
|
||||
} to getString(R.string.attendance_tab_days),
|
||||
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_MONTHS)
|
||||
} to getString(R.string.attendance_tab_months),
|
||||
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_TYPES)
|
||||
} to getString(R.string.attendance_tab_types),
|
||||
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_LIST)
|
||||
} to getString(R.string.attendance_tab_list)
|
||||
)
|
||||
)
|
||||
b.viewPager.apply {
|
||||
offscreenPageLimit = 1
|
||||
adapter = pagerAdapter
|
||||
currentItem = pageSelection
|
||||
addOnPageSelectedListener {
|
||||
pageSelection = it
|
||||
app.profile.config.attendance.attendancePageSelection = it
|
||||
}
|
||||
b.tabLayout.setupWithViewPager(this)
|
||||
override var savedPageSelection
|
||||
get() = app.profile.config.attendance.attendancePageSelection
|
||||
set(value) {
|
||||
app.profile.config.attendance.attendancePageSelection = value
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMarkAsReadType() = MetadataType.ATTENDANCE
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_attendance_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
AttendanceConfigDialog(activity, true, null, null).show()
|
||||
},
|
||||
)
|
||||
|
||||
override fun getTabLayout() = b.tabLayout
|
||||
override fun getViewPager() = b.viewPager
|
||||
override suspend fun onCreatePages() = listOf(
|
||||
AttendanceSummaryFragment() to getString(R.string.attendance_tab_summary),
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_DAYS)
|
||||
} to getString(R.string.attendance_tab_days),
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_MONTHS)
|
||||
} to getString(R.string.attendance_tab_months),
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_TYPES)
|
||||
} to getString(R.string.attendance_tab_types),
|
||||
AttendanceListFragment().apply {
|
||||
arguments = Bundle("viewType" to VIEW_LIST)
|
||||
} to getString(R.string.attendance_tab_list)
|
||||
)
|
||||
}
|
||||
|
@ -5,13 +5,12 @@
|
||||
package pl.szczodrzynski.edziennik.ui.attendance
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||
@ -22,41 +21,20 @@ import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.attendance.models.AttendanceDayRange
|
||||
import pl.szczodrzynski.edziennik.ui.attendance.models.AttendanceMonth
|
||||
import pl.szczodrzynski.edziennik.ui.attendance.models.AttendanceTypeGroup
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSubject
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "AttendanceListFragment"
|
||||
}
|
||||
class AttendanceListFragment : BaseFragment<AttendanceListFragmentBinding, MainActivity>(
|
||||
inflater = AttendanceListFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: AttendanceListFragmentBinding
|
||||
override fun getRefreshScrollingView() = b.list
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
private val manager
|
||||
get() = app.attendanceManager
|
||||
private var viewType = AttendanceFragment.VIEW_DAYS
|
||||
private var expandSubjectId = 0L
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = AttendanceListFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
if (!isAdded) return@startCoroutineTimer
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
viewType = arguments?.getInt("viewType") ?: AttendanceFragment.VIEW_DAYS
|
||||
expandSubjectId = arguments?.getLong("gradesSubjectId") ?: 0L
|
||||
|
||||
@ -77,11 +55,9 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
||||
b.list.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addOnScrollListener(onScrollListener)
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
setSwipeToRefresh(adapter.items.isNullOrEmpty())
|
||||
|
||||
if (firstRun) {
|
||||
expandSubject(adapter)
|
||||
@ -90,7 +66,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
||||
|
||||
// show/hide relevant views
|
||||
b.progressBar.isVisible = false
|
||||
if (adapter.items.isNullOrEmpty()) {
|
||||
if (adapter.items.isEmpty()) {
|
||||
b.list.isVisible = false
|
||||
b.noData.isVisible = true
|
||||
} else {
|
||||
@ -102,7 +78,7 @@ class AttendanceListFragment : LazyFragment(), CoroutineScope {
|
||||
adapter.onAttendanceClick = {
|
||||
AttendanceDetailsDialog(activity, it).show()
|
||||
}
|
||||
}; return true}
|
||||
}
|
||||
|
||||
private fun expandSubject(adapter: AttendanceAdapter) {
|
||||
var expandSubjectModel: GradesSubject? = null
|
||||
|
@ -6,9 +6,6 @@ package pl.szczodrzynski.edziennik.ui.attendance
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.AccelerateDecelerateInterpolator
|
||||
import android.view.animation.Animation
|
||||
import android.view.animation.Transformation
|
||||
@ -19,8 +16,12 @@ import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.*
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Attendance
|
||||
import pl.szczodrzynski.edziennik.data.db.full.AttendanceFull
|
||||
import pl.szczodrzynski.edziennik.databinding.AttendanceSummaryFragmentBinding
|
||||
@ -30,43 +31,26 @@ import pl.szczodrzynski.edziennik.ext.setText
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.attendance.AttendanceFragment.Companion.VIEW_SUMMARY
|
||||
import pl.szczodrzynski.edziennik.ui.attendance.models.AttendanceSubject
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSubject
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
||||
class AttendanceSummaryFragment : BaseFragment<AttendanceSummaryFragmentBinding, MainActivity>(
|
||||
inflater = AttendanceSummaryFragmentBinding::inflate,
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "AttendanceSummaryFragment"
|
||||
private var periodSelection = 0
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: AttendanceSummaryFragmentBinding
|
||||
override fun getRefreshScrollingView() = b.list
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
private val manager
|
||||
get() = app.attendanceManager
|
||||
private var expandSubjectId = 0L
|
||||
private var attendance = listOf<AttendanceFull>()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = AttendanceSummaryFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
if (!isAdded) return@startCoroutineTimer
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
expandSubjectId = arguments?.getLong("gradesSubjectId") ?: 0L
|
||||
|
||||
val adapter = AttendanceAdapter(activity, VIEW_SUMMARY)
|
||||
@ -91,7 +75,6 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
setSwipeToRefresh(adapter.items.isNullOrEmpty())
|
||||
|
||||
if (firstRun) {
|
||||
expandSubject(adapter)
|
||||
@ -100,7 +83,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
||||
|
||||
// show/hide relevant views
|
||||
b.progressBar.isVisible = false
|
||||
if (adapter.items.isNullOrEmpty()) {
|
||||
if (adapter.items.isEmpty()) {
|
||||
b.statsLayout.isVisible = false
|
||||
b.list.isVisible = false
|
||||
b.noData.isVisible = true
|
||||
@ -144,7 +127,7 @@ class AttendanceSummaryFragment : LazyFragment(), CoroutineScope {
|
||||
adapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}; return true}
|
||||
}
|
||||
|
||||
private fun expandSubject(adapter: AttendanceAdapter) {
|
||||
var expandSubjectModel: GradesSubject? = null
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||
package pl.szczodrzynski.edziennik.ui.base.dialog
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||
package pl.szczodrzynski.edziennik.ui.base.dialog
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||
package pl.szczodrzynski.edziennik.ui.base.dialog
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.viewbinding.ViewBinding
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-10-18.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs.base
|
||||
package pl.szczodrzynski.edziennik.ui.base.dialog
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2024-7-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginActivity
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
internal fun BaseFragment<*, *>.setupCanRefresh() {
|
||||
when (val view = getRefreshScrollingView()) {
|
||||
is RecyclerView -> {
|
||||
canRefresh = !view.canScrollVertically(-1)
|
||||
view.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
// disable refresh when scrolled down
|
||||
if (recyclerView.canScrollVertically(-1))
|
||||
canRefresh = false
|
||||
// enable refresh when scrolled to the top and not scrolling anymore
|
||||
else if (newState == RecyclerView.SCROLL_STATE_IDLE)
|
||||
canRefresh = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
is View -> {
|
||||
canRefresh = !view.canScrollVertically(-1)
|
||||
var isTouched = false
|
||||
view.setOnTouchListener { _, event ->
|
||||
// keep track of the touch state
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> isTouched = false
|
||||
MotionEvent.ACTION_DOWN -> isTouched = true
|
||||
}
|
||||
// disable refresh when scrolled down
|
||||
if (view.canScrollVertically(-1))
|
||||
canRefresh = false
|
||||
// enable refresh when scrolled to the top and not touching anymore
|
||||
else if (!isTouched)
|
||||
canRefresh = true
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
// dispatch the default value to the activity
|
||||
canRefresh = canRefresh
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseFragment<*, *>.setupMainActivity(activity: MainActivity) {
|
||||
val items = getBottomSheetItems().toMutableList()
|
||||
getMarkAsReadType()?.let { metadataType ->
|
||||
if (items.isNotEmpty())
|
||||
items += BottomSheetSeparatorItem(true)
|
||||
items += BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_mark_as_read)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
launch(Dispatchers.IO) {
|
||||
app.db.metadataDao().setAllSeen(app.profileId, metadataType, true)
|
||||
}
|
||||
Toast.makeText(
|
||||
activity,
|
||||
R.string.main_menu_mark_as_read_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
if (items.isNotEmpty()) {
|
||||
activity.navView.bottomSheet.prependItems(*items.toTypedArray())
|
||||
}
|
||||
|
||||
getFab()?.let { (text, icon) ->
|
||||
activity.navView.bottomBar.apply {
|
||||
fabEnable = true
|
||||
fabExtendedText = app.getString(text)
|
||||
fabIcon = icon
|
||||
setFabOnClickListener {
|
||||
launch {
|
||||
onFabClick()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun BaseFragment<*, *>.setupLoginActivity(activity: LoginActivity) {}
|
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2024-7-2.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.fragment
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import com.mikepenz.iconics.typeface.IIcon
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginActivity
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.IBottomSheetItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
abstract class BaseFragment<B : ViewBinding, A : AppCompatActivity>(
|
||||
private val inflater: ((inflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean) -> B)?,
|
||||
) : Fragment(), CoroutineScope {
|
||||
|
||||
internal lateinit var app: App
|
||||
internal lateinit var activity: A
|
||||
internal lateinit var b: B
|
||||
|
||||
private var isViewReady: Boolean = false
|
||||
private var inState: Bundle? = null
|
||||
|
||||
/**
|
||||
* Enables or disables the activity's SwipeRefreshLayout.
|
||||
* Use only if [getRefreshScrollingView] is not used.
|
||||
*
|
||||
* The [PagerFragment] manages its [canRefresh] state
|
||||
* based on the value of the currently selected page.
|
||||
*/
|
||||
internal var canRefresh = false
|
||||
set(value) {
|
||||
field = value
|
||||
(activity as? MainActivity)?.swipeRefreshLayout?.isEnabled =
|
||||
!canRefreshDisabled && value
|
||||
}
|
||||
|
||||
/**
|
||||
* Forcefully disables the activity's SwipeRefreshLayout
|
||||
* if [getRefreshScrollingView] is used.
|
||||
*/
|
||||
internal var canRefreshDisabled = false
|
||||
set(value) {
|
||||
field = value
|
||||
canRefresh = canRefresh
|
||||
}
|
||||
|
||||
private var job = Job()
|
||||
final override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
final override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View? {
|
||||
job.cancel()
|
||||
job = Job()
|
||||
activity = getActivity() as? A ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
// inflate using the constructor parameter or the body method
|
||||
b = this.inflater?.invoke(inflater, container, false)
|
||||
?: inflate(inflater, container, false)
|
||||
?: return null
|
||||
isViewReady = false // reinitialize the view in onResume()
|
||||
inState = savedInstanceState // save the instance state for onResume()
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
try {
|
||||
EventBus.getDefault().register(this)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
|
||||
if (!isAdded || isViewReady)
|
||||
return
|
||||
isViewReady = true
|
||||
setupCanRefresh()
|
||||
(activity as? MainActivity)?.let(::setupMainActivity)
|
||||
(activity as? LoginActivity)?.let(::setupLoginActivity)
|
||||
// let the UI transition for a moment
|
||||
startCoroutineTimer(100L) {
|
||||
if (!isAdded)
|
||||
return@startCoroutineTimer
|
||||
onViewReady(inState)
|
||||
(activity as? MainActivity)?.gainAttention()
|
||||
(activity as? MainActivity)?.gainAttentionFAB()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
try {
|
||||
EventBus.getDefault().unregister(this)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
final override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
isViewReady = false
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
final override fun onViewCreated(view: View, savedInstanceState: Bundle?) =
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
final override fun onViewStateRestored(savedInstanceState: Bundle?) =
|
||||
super.onViewStateRestored(savedInstanceState)
|
||||
|
||||
final override fun onAttach(context: Context) = super.onAttach(context)
|
||||
final override fun onCreate(savedInstanceState: Bundle?) = super.onCreate(savedInstanceState)
|
||||
final override fun onStart() = super.onStart()
|
||||
final override fun onStop() = super.onStop()
|
||||
final override fun onDestroy() = super.onDestroy()
|
||||
final override fun onDetach() = super.onDetach()
|
||||
|
||||
/**
|
||||
* Called if there is no inflater passed in the constructor.
|
||||
* Must return a non-null value.
|
||||
*/
|
||||
open fun inflate(
|
||||
inflater: LayoutInflater,
|
||||
parent: ViewGroup?,
|
||||
attachToParent: Boolean,
|
||||
): B? = null
|
||||
|
||||
/**
|
||||
* Called to retrieve the scrolling view contained in the fragment.
|
||||
* The scrolling view is configured to act nicely with the SwipeRefreshLayout.
|
||||
*/
|
||||
open fun getRefreshScrollingView(): View? = null
|
||||
|
||||
/**
|
||||
* Called to retrieve the FAB label resource and the icon.
|
||||
* If provided, a FAB is added and shown automatically.
|
||||
*/
|
||||
open fun getFab(): Pair<Int, IIcon>? = null
|
||||
|
||||
/**
|
||||
* Called to retrieve the [MetadataType] of items displayed by the fragment.
|
||||
* If provided, a "mark as read" item is added to the bottom sheet.
|
||||
*/
|
||||
open fun getMarkAsReadType(): MetadataType? = null
|
||||
|
||||
/**
|
||||
* Called to retrieve any extra bottom sheet items that should be displayed.
|
||||
*/
|
||||
open fun getBottomSheetItems() = listOf<IBottomSheetItem<*>>()
|
||||
|
||||
/**
|
||||
* Called after the fragment is initialized (default) or when is becomes visible (pager).
|
||||
*
|
||||
* Perform view initialization and other tasks, if necessary. Remember to call super
|
||||
* if used in a [PagerFragment].
|
||||
*/
|
||||
open suspend fun onViewReady(savedInstanceState: Bundle?) {}
|
||||
|
||||
/**
|
||||
* Called when the FAB is clicked (if enabled).
|
||||
*/
|
||||
open suspend fun onFabClick() {}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2024-7-3.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.ext.set
|
||||
|
||||
abstract class PagerFragment<B : ViewBinding, A : AppCompatActivity>(
|
||||
inflater: ((inflater: LayoutInflater, parent: ViewGroup?, attachToParent: Boolean) -> B)?,
|
||||
) : BaseFragment<B, A>(inflater) {
|
||||
|
||||
private lateinit var pages: List<Pair<Fragment, String>>
|
||||
private val fragmentCache = mutableMapOf<Int, Fragment>()
|
||||
|
||||
/**
|
||||
* Stores the default page index that is activated when
|
||||
* entering the fragment. Updated every time a new page
|
||||
* is selected.
|
||||
*
|
||||
* Override with a getter and setter to make it backed by
|
||||
* e.g. app.config. Set this value before calling super.[onViewReady]
|
||||
* to provide a one-time default.
|
||||
*/
|
||||
protected open var savedPageSelection = -1
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
if (savedPageSelection == -1)
|
||||
savedPageSelection = savedInstanceState?.getInt("pageSelection") ?: 0
|
||||
|
||||
pages = onCreatePages()
|
||||
|
||||
val adapter = object : FragmentStateAdapter(this) {
|
||||
override fun getItemCount() = getPageCount()
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
val fragment = getPageFragment(position)
|
||||
fragmentCache[position] = fragment
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
|
||||
getViewPager().let {
|
||||
it.offscreenPageLimit = 1
|
||||
it.adapter = adapter
|
||||
it.setCurrentItem(savedPageSelection, false)
|
||||
it.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
canRefresh = when (state) {
|
||||
ViewPager2.SCROLL_STATE_IDLE -> {
|
||||
val fragment =
|
||||
fragmentCache[it.currentItem] as? BaseFragment<*, *>
|
||||
fragment != null && !fragment.canRefreshDisabled && fragment.canRefresh
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
savedPageSelection = position
|
||||
launch {
|
||||
this@PagerFragment.onPageSelected(position)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
TabLayoutMediator(getTabLayout(), getViewPager()) { tab, position ->
|
||||
tab.text = getPageTitle(position)
|
||||
}.attach()
|
||||
|
||||
onPageSelected(savedPageSelection)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState["pageSelection"] = getViewPager().currentItem
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates to the specified page with a smooth scroll animation.
|
||||
*
|
||||
* To navigate without smooth scroll, use [savedPageSelection] instead
|
||||
* to provide a default page selection.
|
||||
*/
|
||||
protected fun goToPage(position: Int) {
|
||||
getViewPager().setCurrentItem(position, true)
|
||||
savedPageSelection = position
|
||||
launch {
|
||||
onPageSelected(position)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to retrieve the [TabLayout] view of the pager fragment.
|
||||
*/
|
||||
abstract fun getTabLayout(): TabLayout
|
||||
|
||||
/**
|
||||
* Called to retrieve the [ViewPager2] view of the pager fragment.
|
||||
*/
|
||||
abstract fun getViewPager(): ViewPager2
|
||||
|
||||
/**
|
||||
* Called to retrieve a list of fragments (and their titles) for the pager.
|
||||
* Only used with the default implementation of [getPageCount], [getPageFragment]
|
||||
* and [getPageTitle].
|
||||
*/
|
||||
open suspend fun onCreatePages() = listOf<Pair<Fragment, String>>()
|
||||
|
||||
open fun getPageCount() = pages.size
|
||||
open fun getPageFragment(position: Int) = pages[position].first
|
||||
open fun getPageTitle(position: Int) = pages[position].second
|
||||
|
||||
/**
|
||||
* Called when a new page is selected, by either:
|
||||
* - opening the fragment for the first time (default page),
|
||||
* - calling [goToPage], or
|
||||
* - navigating to another page by the user.
|
||||
*
|
||||
* The [savedPageSelection] is updated before this method is called.
|
||||
*/
|
||||
open suspend fun onPageSelected(position: Int) {}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-30.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.lazypager
|
||||
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
|
||||
class FragmentLazyPagerAdapter(
|
||||
fragmentManager: FragmentManager,
|
||||
swipeRefreshLayout: SwipeRefreshLayout? = null,
|
||||
val fragments: List<Pair<LazyFragment, CharSequence>>
|
||||
) : LazyPagerAdapter(fragmentManager, swipeRefreshLayout) {
|
||||
override fun getPage(position: Int) = fragments[position].first
|
||||
override fun getPageTitle(position: Int) = fragments[position].second
|
||||
override fun getCount() = fragments.size
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.lazypager
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
abstract class LazyFragment : Fragment() {
|
||||
private var isPageCreated = false
|
||||
internal var position = -1
|
||||
internal var swipeRefreshLayoutCallback: ((position: Int, isEnabled: Boolean) -> Unit)? = null
|
||||
internal var onPageDestroy: ((position: Int, outState: Bundle?) -> Unit?)? = null
|
||||
|
||||
/**
|
||||
* Called when the page is first shown, or if previous
|
||||
* [onPageCreated] returned false
|
||||
*
|
||||
* @return true if the view is set up
|
||||
* @return false if the setup failed. The method may be then called
|
||||
* again, when page becomes visible.
|
||||
*/
|
||||
abstract fun onPageCreated(): Boolean
|
||||
|
||||
fun enableSwipeToRefresh() = swipeRefreshLayoutCallback?.invoke(position, true)
|
||||
fun disableSwipeToRefresh() = swipeRefreshLayoutCallback?.invoke(position, false)
|
||||
fun setSwipeToRefresh(enabled: Boolean) = swipeRefreshLayoutCallback?.invoke(position, enabled)
|
||||
|
||||
val onScrollListener: RecyclerView.OnScrollListener
|
||||
get() = object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
if (recyclerView.canScrollVertically(-1))
|
||||
disableSwipeToRefresh()
|
||||
if (!recyclerView.canScrollVertically(-1) && newState == RecyclerView.SCROLL_STATE_IDLE)
|
||||
enableSwipeToRefresh()
|
||||
}
|
||||
}
|
||||
|
||||
internal fun createPage() {
|
||||
if (!isPageCreated && isAdded) {
|
||||
isPageCreated = onPageCreated()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
isPageCreated = false
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
createPage()
|
||||
super.onResume()
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.lazypager
|
||||
|
||||
import android.util.SparseBooleanArray
|
||||
import androidx.core.util.set
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
|
||||
abstract class LazyPagerAdapter(fragmentManager: FragmentManager, val swipeRefreshLayout: SwipeRefreshLayout? = null) : FragmentStatePagerAdapter(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
|
||||
internal val enabledList = SparseBooleanArray()
|
||||
private val refreshLayoutCallback: (position: Int, isEnabled: Boolean) -> Unit = { position, isEnabled ->
|
||||
swipeRefreshLayout?.isEnabled = isEnabled
|
||||
if (position > -1)
|
||||
enabledList[position] = isEnabled
|
||||
}
|
||||
final override fun getItem(position: Int): LazyFragment {
|
||||
return getPage(position).also {
|
||||
it.position = position
|
||||
it.swipeRefreshLayoutCallback = refreshLayoutCallback
|
||||
}
|
||||
}
|
||||
abstract fun getPage(position: Int): LazyFragment
|
||||
abstract override fun getPageTitle(position: Int): CharSequence
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-29.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base.lazypager
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
|
||||
class LazyViewPager @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : ViewPager(context, attrs) {
|
||||
|
||||
private var pageSelection = -1
|
||||
private var scrollState = 0
|
||||
|
||||
init {
|
||||
addOnPageChangeListener(object : OnPageChangeListener {
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
scrollState = state
|
||||
(adapter as? LazyPagerAdapter)?.let {
|
||||
it.swipeRefreshLayout?.isEnabled = state == SCROLL_STATE_IDLE && it.enabledList[pageSelection, true]
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
pageSelection = position
|
||||
(adapter as? LazyPagerAdapter)?.let {
|
||||
it.swipeRefreshLayout?.isEnabled = scrollState == SCROLL_STATE_IDLE && it.enabledList[pageSelection, true]
|
||||
val fragment = adapter?.instantiateItem(this@LazyViewPager, position)
|
||||
val lazyFragment = fragment as? LazyFragment
|
||||
lazyFragment?.createPage()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
@ -29,9 +29,9 @@ import pl.szczodrzynski.navlib.colorAttr
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class AttachmentAdapter(
|
||||
val context: Context,
|
||||
val onAttachmentClick: (item: Item) -> Unit,
|
||||
val onAttachmentLongClick: ((view: Chip, item: Item) -> Unit)? = null
|
||||
val context: Context,
|
||||
val onAttachmentClick: (item: Item) -> Unit,
|
||||
val onAttachmentLongClick: ((view: Chip, item: Item) -> Unit)? = null
|
||||
) : RecyclerView.Adapter<AttachmentAdapter.ViewHolder>(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "AttachmentAdapter"
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-1.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
@ -19,7 +19,6 @@ import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||
import pl.szczodrzynski.edziennik.data.api.events.AttachmentGetEvent
|
||||
import pl.szczodrzynski.edziennik.ext.get
|
||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
@ -46,7 +45,7 @@ class AttachmentsView @JvmOverloads constructor(
|
||||
val activity = context as? AppCompatActivity ?: return
|
||||
val list = this as? RecyclerView ?: return
|
||||
|
||||
val profileId = arguments.get<Int>("profileId") ?: return
|
||||
val profileId = arguments.getInt("profileId")
|
||||
val attachmentIds = arguments.getLongArray("attachmentIds") ?: return
|
||||
val attachmentNames = arguments.getStringArray("attachmentNames") ?: return
|
||||
val attachmentSizes = arguments.getLongArray("attachmentSizes")
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-4-14.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2024-6-20.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-3-7.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-23.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.views
|
||||
package pl.szczodrzynski.edziennik.ui.base.views
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
@ -1,63 +1,32 @@
|
||||
package pl.szczodrzynski.edziennik.ui.behaviour
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.AsyncTask
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import android.widget.Toast
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.Fragment
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.App.Companion.profileId
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Notice
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.data.db.full.NoticeFull
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentBehaviourBinding
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.utils.Themes.getPrimaryTextColor
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
|
||||
class BehaviourFragment : Fragment() {
|
||||
class BehaviourFragment : BaseFragment<FragmentBehaviourBinding, MainActivity>(
|
||||
inflater = FragmentBehaviourBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentBehaviourBinding
|
||||
override fun getMarkAsReadType() = MetadataType.NOTICE
|
||||
|
||||
private var displayMode = MODE_YEAR
|
||||
private var noticeList: List<NoticeFull>? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_behaviour, container, false)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (app == null || activity == null || b == null || !isAdded) return
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_mark_as_read)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_eye_check_outline)
|
||||
.withOnClickListener { v3: View? ->
|
||||
activity.bottomSheet.close()
|
||||
AsyncTask.execute {
|
||||
App.db.metadataDao().setAllSeen(profileId, MetadataType.NOTICE, true)
|
||||
}
|
||||
Toast.makeText(
|
||||
activity,
|
||||
R.string.main_menu_mark_as_read_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
)
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
b.toggleGroup.check(when (displayMode) {
|
||||
0 -> R.id.allYear
|
||||
1 -> R.id.semester1
|
||||
@ -81,18 +50,8 @@ class BehaviourFragment : Fragment() {
|
||||
val linearLayoutManager = LinearLayoutManager(context)
|
||||
b.noticesView.setHasFixedSize(true)
|
||||
b.noticesView.layoutManager = linearLayoutManager
|
||||
b.noticesView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
if (recyclerView.canScrollVertically(-1)) {
|
||||
b.refreshLayout.isEnabled = false
|
||||
}
|
||||
if (!recyclerView.canScrollVertically(-1) && newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
b.refreshLayout.isEnabled = true
|
||||
}
|
||||
}
|
||||
})
|
||||
App.db.noticeDao().getAll(profileId).observe(viewLifecycleOwner) { notices: List<NoticeFull>? ->
|
||||
if (app == null || activity == null || b == null || !isAdded) return@observe
|
||||
if (!isAdded) return@observe
|
||||
if (notices == null) {
|
||||
b.noticesView.visibility = View.GONE
|
||||
b.noticesNoData.visibility = View.VISIBLE
|
||||
|
@ -13,7 +13,7 @@ import kotlinx.coroutines.*
|
||||
import okhttp3.*
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.RecaptchaDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import java.io.IOException
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
|
@ -11,7 +11,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.RecaptchaViewBinding
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
|
||||
class RecaptchaPromptDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -4,73 +4,20 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.debug
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.databinding.TemplateFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.addOnPageSelectedListener
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.FragmentLazyPagerAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginActivity
|
||||
import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import pl.szczodrzynski.edziennik.databinding.BasePagerFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.PagerFragment
|
||||
|
||||
class LabFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "LabFragment"
|
||||
var pageSelection = 0
|
||||
}
|
||||
class LabFragment : PagerFragment<BasePagerFragmentBinding, AppCompatActivity>(
|
||||
inflater = BasePagerFragmentBinding::inflate,
|
||||
), CoroutineScope {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: AppCompatActivity
|
||||
private lateinit var b: TemplateFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as AppCompatActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = TemplateFragmentBinding.inflate(inflater)
|
||||
when (activity) {
|
||||
is MainActivity -> b.refreshLayout.setParent((activity as MainActivity).swipeRefreshLayout)
|
||||
is LoginActivity -> b.refreshLayout.setParent((activity as LoginActivity).swipeRefreshLayout)
|
||||
}
|
||||
b.refreshLayout.isEnabled = false
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
|
||||
val pagerAdapter = FragmentLazyPagerAdapter(
|
||||
parentFragmentManager,
|
||||
b.refreshLayout,
|
||||
listOf(
|
||||
LabPageFragment() to "click me",
|
||||
LabProfileFragment() to "JSON",
|
||||
LabPlaygroundFragment() to "Playground",
|
||||
)
|
||||
)
|
||||
b.viewPager.apply {
|
||||
offscreenPageLimit = 1
|
||||
adapter = pagerAdapter
|
||||
currentItem = pageSelection
|
||||
addOnPageSelectedListener {
|
||||
pageSelection = it
|
||||
}
|
||||
b.tabLayout.setupWithViewPager(this)
|
||||
}
|
||||
}
|
||||
override fun getTabLayout() = b.tabLayout
|
||||
override fun getViewPager() = b.viewPager
|
||||
override suspend fun onCreatePages() = listOf(
|
||||
LabPageFragment() to "click me",
|
||||
LabProfileFragment() to "JSON",
|
||||
LabPlaygroundFragment() to "Playground",
|
||||
)
|
||||
}
|
||||
|
@ -6,9 +6,6 @@ package pl.szczodrzynski.edziennik.ui.debug
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Process
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
@ -16,47 +13,38 @@ import androidx.sqlite.db.SimpleSQLiteQuery
|
||||
import com.chuckerteam.chucker.api.Chucker
|
||||
import com.chuckerteam.chucker.api.Chucker.SCREEN_HTTP
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.config.Config
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.interceptor.SignatureInterceptor
|
||||
import pl.szczodrzynski.edziennik.data.config.Config
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.EventType.Companion.SOURCE_DEFAULT
|
||||
import pl.szczodrzynski.edziennik.databinding.LabFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ext.asBoldSpannable
|
||||
import pl.szczodrzynski.edziennik.ext.asColoredSpannable
|
||||
import pl.szczodrzynski.edziennik.ext.asItalicSpannable
|
||||
import pl.szczodrzynski.edziennik.ext.asUnderlineSpannable
|
||||
import pl.szczodrzynski.edziennik.ext.concat
|
||||
import pl.szczodrzynski.edziennik.ext.onChange
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ext.resolveAttr
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ext.takeValue
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ProfileRemoveDialog
|
||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||
import pl.szczodrzynski.fslogin.decode
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class LabPageFragment : LazyFragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "LabPageFragment"
|
||||
}
|
||||
class LabPageFragment : BaseFragment<LabFragmentBinding, AppCompatActivity>(
|
||||
inflater = LabFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: AppCompatActivity
|
||||
private lateinit var b: LabFragmentBinding
|
||||
override fun getRefreshScrollingView() = b.scrollView
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as AppCompatActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = LabFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean {
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
b.app = app
|
||||
|
||||
if (app.profile.id == 0) {
|
||||
@ -222,7 +210,5 @@ class LabPageFragment : LazyFragment(), CoroutineScope {
|
||||
}.concat("\n\n")
|
||||
b.cookies.text = text
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -5,51 +5,21 @@
|
||||
package pl.szczodrzynski.edziennik.ui.debug
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.databinding.LabPlaygroundBinding
|
||||
import pl.szczodrzynski.edziennik.ext.asColoredSpannable
|
||||
import pl.szczodrzynski.edziennik.ext.concat
|
||||
import pl.szczodrzynski.edziennik.ext.resolveAttr
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class LabPlaygroundFragment : LazyFragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "LabPlaygroundFragment"
|
||||
}
|
||||
class LabPlaygroundFragment : BaseFragment<LabPlaygroundBinding, AppCompatActivity>(
|
||||
inflater = LabPlaygroundBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: AppCompatActivity
|
||||
private lateinit var b: LabPlaygroundBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View? {
|
||||
activity = (getActivity() as AppCompatActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = LabPlaygroundBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean {
|
||||
override fun getRefreshScrollingView() = b.root
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
Timber.d("textColorSecondary: ${android.R.attr.textColorSecondary.resolveAttr(activity)}")
|
||||
b.spanTest1.text = listOf(
|
||||
"Text:", "android:textColorSecondary spannable (activity)".asColoredSpannable(
|
||||
@ -62,7 +32,5 @@ class LabPlaygroundFragment : LazyFragment(), CoroutineScope {
|
||||
android.R.attr.textColorSecondary.resolveAttr(context)
|
||||
)
|
||||
).concat(" ")
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,6 @@
|
||||
package pl.szczodrzynski.edziennik.ui.debug
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@ -16,48 +13,30 @@ import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonParser
|
||||
import com.google.gson.JsonPrimitive
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.databinding.TemplateListPageFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.login.LoginActivity
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class LabProfileFragment : LazyFragment(), CoroutineScope {
|
||||
class LabProfileFragment : BaseFragment<TemplateListPageFragmentBinding, AppCompatActivity>(
|
||||
inflater = TemplateListPageFragmentBinding::inflate,
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "LabProfileFragment"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: AppCompatActivity
|
||||
private lateinit var b: TemplateListPageFragmentBinding
|
||||
override fun getRefreshScrollingView() = b.list
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
private lateinit var adapter: LabJsonAdapter
|
||||
private val loginStore by lazy {
|
||||
app.db.loginStoreDao().getByIdNow(app.profile.loginStoreId)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as AppCompatActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = TemplateListPageFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
adapter = LabJsonAdapter(activity, onJsonElementClick = { item ->
|
||||
try {
|
||||
var parent: Any = Unit
|
||||
@ -117,7 +96,12 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
|
||||
is JsonArray -> {
|
||||
|
||||
}
|
||||
is HashMap<*, *> -> app.config[objName] = input
|
||||
is HashMap<*, *> -> {
|
||||
if ("(profile)" in item.key)
|
||||
app.profile.config[objName] = input
|
||||
else
|
||||
app.config[objName] = input
|
||||
}
|
||||
else -> {
|
||||
val field = parent::class.java.getDeclaredField(objName)
|
||||
field.isAccessible = true
|
||||
@ -165,15 +149,13 @@ class LabProfileFragment : LazyFragment(), CoroutineScope {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
addOnScrollListener(onScrollListener)
|
||||
}
|
||||
|
||||
// show/hide relevant views
|
||||
b.progressBar.isVisible = false
|
||||
b.list.isVisible = true
|
||||
b.noData.isVisible = false
|
||||
|
||||
}; return true }
|
||||
}
|
||||
|
||||
private fun showJson() {
|
||||
val json = JsonObject().also { json ->
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncBinding
|
||||
import pl.szczodrzynski.edziennik.ext.resolveDrawable
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
class BellSyncDialog(
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Lesson
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogBellSyncTimeChooseBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
@ -9,7 +9,7 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ext.dp
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ViewDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ViewDialog
|
||||
import pl.szczodrzynski.edziennik.utils.BetterLinkMovementMethod
|
||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-2-16.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.error
|
||||
package pl.szczodrzynski.edziennik.ui.dialogs
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class ErrorDetailsDialog(
|
||||
activity: AppCompatActivity,
|
@ -10,7 +10,7 @@ import kotlinx.coroutines.*
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class ProfileRemoveDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -8,7 +8,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import me.dm7.barcodescanner.zxing.ZXingScannerView
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ext.dp
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ViewDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ViewDialog
|
||||
|
||||
class QrScannerDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.StyledTextDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.isNightMode
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.DefaultTextStyles
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.SIMPLE
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.StylingConfig
|
||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogConfigAgendaBinding
|
||||
import pl.szczodrzynski.edziennik.ext.onChange
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ConfigDialog
|
||||
|
||||
class AgendaConfigDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -6,7 +6,7 @@ package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class AppLanguageDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -9,7 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.AttendanceConfigDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.onChange
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ConfigDialog
|
||||
|
||||
class AttendanceConfigDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -10,7 +10,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogEditTextBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.models.Time
|
||||
|
||||
class BellSyncConfigDialog(
|
||||
|
@ -16,7 +16,7 @@ import pl.szczodrzynski.edziennik.ext.join
|
||||
import pl.szczodrzynski.edziennik.ext.onChange
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ext.setOnSelectedListener
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.COLOR_MODE_DEFAULT
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.COLOR_MODE_WEIGHTED
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.ORDER_BY_DATE_DESC
|
||||
|
@ -8,7 +8,7 @@ import android.view.LayoutInflater
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesConfigDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ConfigDialog
|
||||
|
||||
class MessagesConfigDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -11,7 +11,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ext.resolveString
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTargetLocation
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class MiniMenuConfigDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -9,7 +9,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.enums.NotificationType
|
||||
import pl.szczodrzynski.edziennik.ext.resolveString
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class NotificationFilterDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -16,7 +16,7 @@ import pl.szczodrzynski.edziennik.ext.dp
|
||||
import pl.szczodrzynski.edziennik.ext.onChange
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ProfileRemoveDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
|
||||
class ProfileConfigDialog(
|
||||
activity: MainActivity,
|
||||
|
@ -9,7 +9,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ext.HOUR
|
||||
import pl.szczodrzynski.edziennik.ext.MINUTE
|
||||
import pl.szczodrzynski.edziennik.ext.getSyncInterval
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class SyncIntervalDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -7,7 +7,7 @@ package pl.szczodrzynski.edziennik.ui.dialogs.settings
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.enums.Theme
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class ThemeChooserDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -9,7 +9,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.TimetableConfigDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Intent
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.ConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
|
||||
|
||||
class TimetableConfigDialog(
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.RegisterAvailabilityStatus
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogRegisterUnavailableBinding
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class RegisterUnavailableDialog(
|
||||
|
@ -6,7 +6,7 @@ package pl.szczodrzynski.edziennik.ui.dialogs.sync
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
|
||||
class ServerMessageDialog(
|
||||
activity: AppCompatActivity,
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.data.enums.FeatureType
|
||||
import pl.szczodrzynski.edziennik.ext.hasFeature
|
||||
import pl.szczodrzynski.edziennik.ext.resolveString
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
||||
|
||||
class SyncViewListDialog(
|
||||
|
@ -10,7 +10,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.response.Update
|
||||
import pl.szczodrzynski.edziennik.ext.Intent
|
||||
import pl.szczodrzynski.edziennik.sync.UpdateDownloaderService
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||
|
||||
|
@ -19,7 +19,7 @@ import pl.szczodrzynski.edziennik.databinding.UpdateProgressDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.getInt
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.core.work.UpdateStateEvent
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
|
||||
class UpdateProgressDialog(
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-13.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.error
|
||||
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogLessonDetailsBinding
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class ErrorDialog(
|
||||
val activity: AppCompatActivity,
|
||||
val exception: Exception
|
||||
) : CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "ErrorDialog"
|
||||
}
|
||||
|
||||
private lateinit var job: Job
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
private val app by lazy { activity.application as App }
|
||||
private lateinit var b: DialogLessonDetailsBinding
|
||||
private lateinit var dialog: AlertDialog
|
||||
|
||||
init { run {
|
||||
job = Job()
|
||||
|
||||
dialog = MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.error_occured)
|
||||
.setMessage(exception.message + "\n" + Log.getStackTraceString(exception))
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
.show()
|
||||
}}
|
||||
}
|
@ -28,7 +28,7 @@ import pl.szczodrzynski.edziennik.data.db.full.EventFull
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogEventDetailsBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.notes.setupNotesButton
|
||||
import pl.szczodrzynski.edziennik.ui.timetable.TimetableFragment
|
||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||
|
@ -44,9 +44,9 @@ import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ext.removeFromParent
|
||||
import pl.szczodrzynski.edziennik.ext.setText
|
||||
import pl.szczodrzynski.edziennik.ext.setTintColor
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.RegistrationConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.views.TimeDropdown.Companion.DISPLAY_LESSONS
|
||||
import pl.szczodrzynski.edziennik.ui.base.views.TimeDropdown.Companion.DISPLAY_LESSONS
|
||||
import pl.szczodrzynski.edziennik.utils.Anim
|
||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.SIMPLE
|
||||
|
@ -6,20 +6,18 @@ import android.graphics.BitmapFactory
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupMenu
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import coil.imageLoader
|
||||
import coil.request.ImageRequest
|
||||
import com.github.bassaer.chatmessageview.model.IChatUser
|
||||
import com.github.bassaer.chatmessageview.model.Message
|
||||
import com.github.bassaer.chatmessageview.view.ChatView
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
@ -31,25 +29,16 @@ import pl.szczodrzynski.edziennik.data.db.entity.FeedbackMessage
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentFeedbackBinding
|
||||
import pl.szczodrzynski.edziennik.ext.crc16
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.openUrl
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
import java.util.Calendar
|
||||
import kotlin.collections.set
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class FeedbackFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "FeedbackFragment"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: AppCompatActivity
|
||||
private lateinit var b: FragmentFeedbackBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
class FeedbackFragment : BaseFragment<FragmentFeedbackBinding, AppCompatActivity>(
|
||||
inflater = FragmentFeedbackBinding::inflate,
|
||||
) {
|
||||
|
||||
private val chatView: ChatView by lazy { b.chatView }
|
||||
private val api by lazy { SzkolnyApi(app) }
|
||||
@ -58,18 +47,6 @@ class FeedbackFragment : Fragment(), CoroutineScope {
|
||||
|
||||
private var receiver: BroadcastReceiver? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as AppCompatActivity?) ?: return null
|
||||
if (context == null)
|
||||
return null
|
||||
app = activity.application as App
|
||||
// activity, context and profile is valid
|
||||
b = FragmentFeedbackBinding.inflate(inflater)
|
||||
// prevent doubled received messages on enter
|
||||
EventBus.getDefault().removeStickyEvent(FeedbackMessageEvent::class.java)
|
||||
return b.root
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
fun onFeedbackMessageEvent(event: FeedbackMessageEvent) {
|
||||
EventBus.getDefault().removeStickyEvent(event)
|
||||
@ -143,10 +120,8 @@ class FeedbackFragment : Fragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
// TODO check if app, activity, b can be null
|
||||
if (!isAdded)
|
||||
return
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
EventBus.getDefault().removeStickyEvent(FeedbackMessageEvent::class.java)
|
||||
|
||||
b.faqText.setOnClickListener { openFaq() }
|
||||
b.faqButton.setOnClickListener { openFaq() }
|
||||
@ -163,46 +138,44 @@ class FeedbackFragment : Fragment(), CoroutineScope {
|
||||
setMessageMarginBottom(5)
|
||||
}
|
||||
|
||||
launch {
|
||||
val messages = withContext(Dispatchers.Default) {
|
||||
val messages = app.db.feedbackMessageDao().allNow
|
||||
isDev = App.devMode && messages.any { it.deviceId != null }
|
||||
messages
|
||||
}
|
||||
val messages = withContext(Dispatchers.IO) {
|
||||
val messages = app.db.feedbackMessageDao().allNow
|
||||
isDev = App.devMode && messages.any { it.deviceId != null }
|
||||
messages
|
||||
}
|
||||
|
||||
b.targetDeviceLayout.visibility = if (isDev) View.VISIBLE else View.GONE
|
||||
b.targetDeviceDropDown.onClick {
|
||||
launchDeviceSelection()
|
||||
}
|
||||
b.targetDeviceLayout.visibility = if (isDev) View.VISIBLE else View.GONE
|
||||
b.targetDeviceDropDown.onClick {
|
||||
launchDeviceSelection()
|
||||
}
|
||||
|
||||
if (isDev) {
|
||||
messages.firstOrNull { it.received && it.devId == null }?.let {
|
||||
currentDeviceId = it.deviceId
|
||||
if (isDev) {
|
||||
messages.firstOrNull { it.received && it.devId == null }?.let {
|
||||
currentDeviceId = it.deviceId
|
||||
b.targetDeviceDropDown.setText("${it.senderName} (${it.deviceId}) - ${it.deviceName}")
|
||||
}
|
||||
// handle notification intent
|
||||
arguments?.getString("feedbackMessageDeviceId")?.let { deviceId ->
|
||||
messages.firstOrNull { it.received && it.deviceId == deviceId && it.devId == null }?.let {
|
||||
currentDeviceId = deviceId
|
||||
b.targetDeviceDropDown.setText("${it.senderName} (${it.deviceId}) - ${it.deviceName}")
|
||||
}
|
||||
// handle notification intent
|
||||
arguments?.getString("feedbackMessageDeviceId")?.let { deviceId ->
|
||||
messages.firstOrNull { it.received && it.deviceId == deviceId && it.devId == null }?.let {
|
||||
currentDeviceId = deviceId
|
||||
b.targetDeviceDropDown.setText("${it.senderName} (${it.deviceId}) - ${it.deviceName}")
|
||||
}
|
||||
}
|
||||
b.chatLayout.visibility = View.VISIBLE
|
||||
b.inputLayout.visibility = View.GONE
|
||||
}
|
||||
else if (messages.isEmpty()) {
|
||||
b.chatLayout.visibility = View.GONE
|
||||
b.inputLayout.visibility = View.VISIBLE
|
||||
}
|
||||
b.chatLayout.visibility = View.VISIBLE
|
||||
b.inputLayout.visibility = View.GONE
|
||||
}
|
||||
else if (messages.isEmpty()) {
|
||||
b.chatLayout.visibility = View.GONE
|
||||
b.inputLayout.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
loadMessages(messages)
|
||||
loadMessages(messages)
|
||||
|
||||
b.sendButton.onClick {
|
||||
send(b.textInput.text.toString())
|
||||
}
|
||||
chatView.setOnClickSendButtonListener(View.OnClickListener {
|
||||
send(chatView.inputText)
|
||||
})
|
||||
b.sendButton.onClick {
|
||||
send(b.textInput.text.toString())
|
||||
}
|
||||
chatView.setOnClickSendButtonListener {
|
||||
send(chatView.inputText)
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,14 +248,4 @@ class FeedbackFragment : Fragment(), CoroutineScope {
|
||||
private fun openFaq() {
|
||||
openUrl(activity, "http://szkolny.eu/pomoc/")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
EventBus.getDefault().register(this)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
EventBus.getDefault().unregister(this)
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.databinding.DialogGradeDetailsBinding
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ext.setTintColor
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.notes.setupNotesButton
|
||||
import pl.szczodrzynski.edziennik.utils.BetterLink
|
||||
|
@ -4,50 +4,51 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.grades
|
||||
|
||||
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.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.*
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.data.db.full.GradeFull
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesListFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.databinding.GradesListFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.averageOrNull
|
||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.GradesConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.grades.models.GradesAverages
|
||||
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSemester
|
||||
import pl.szczodrzynski.edziennik.ui.grades.models.GradesStats
|
||||
import pl.szczodrzynski.edziennik.ui.grades.models.GradesSubject
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.math.max
|
||||
|
||||
class GradesListFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "GradesFragment"
|
||||
}
|
||||
class GradesListFragment : BaseFragment<GradesListFragmentBinding, MainActivity>(
|
||||
inflater = GradesListFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: GradesListFragmentBinding
|
||||
override fun getMarkAsReadType() = MetadataType.GRADE
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_grades_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
GradesConfigDialog(activity, true, null, null).show()
|
||||
},
|
||||
)
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
private val manager
|
||||
get() = app.gradesManager
|
||||
private val dontCountEnabled
|
||||
@ -56,18 +57,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
||||
get() = manager.dontCountGrades
|
||||
private var expandSubjectId = 0L
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = GradesListFragmentBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { startCoroutineTimer(100L) {
|
||||
if (!isAdded) return@startCoroutineTimer
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
expandSubjectId = arguments?.getLong("gradesSubjectId") ?: 0L
|
||||
|
||||
val adapter = GradesAdapter(activity)
|
||||
@ -92,7 +82,6 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
||||
b.list.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addOnScrollListener(b.refreshLayout.onScrollListener)
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
@ -121,7 +110,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
||||
val otherSemester = subject.semesters.firstOrNull { it != semester }
|
||||
var gradeSumOtherSemester = otherSemester?.averages?.normalWeightedSum
|
||||
var gradeCountOtherSemester = otherSemester?.averages?.normalWeightedCount
|
||||
if (gradeSumOtherSemester ?: 0f == 0f || gradeCountOtherSemester ?: 0f == 0f) {
|
||||
if ((gradeSumOtherSemester ?: 0f) == 0f || (gradeCountOtherSemester ?: 0f) == 0f) {
|
||||
gradeSumOtherSemester = otherSemester?.averages?.normalSum
|
||||
gradeCountOtherSemester = otherSemester?.averages?.normalCount?.toFloat()
|
||||
}
|
||||
@ -137,27 +126,7 @@ class GradesListFragment : Fragment(), CoroutineScope {
|
||||
"finalOtherSemester" to otherSemester?.finalGrade?.value
|
||||
))
|
||||
}
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_grades_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener(View.OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
GradesConfigDialog(activity, true, null, null).show()
|
||||
}),
|
||||
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, MetadataType.GRADE, true) }
|
||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
)
|
||||
activity.gainAttention()
|
||||
}}
|
||||
}
|
||||
|
||||
private fun expandSubject(adapter: GradesAdapter) {
|
||||
var expandSubjectModel: GradesSubject? = null
|
||||
|
@ -4,41 +4,34 @@ import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.os.Bundle
|
||||
import android.text.InputType
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_1_AVG_2_AVG
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_1_AVG_2_SEM
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_1_SEM_2_AVG
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_ALL_GRADES
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Grade
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentGradesEditorBinding
|
||||
import pl.szczodrzynski.edziennik.ext.getFloat
|
||||
import pl.szczodrzynski.edziennik.ext.getInt
|
||||
import pl.szczodrzynski.edziennik.ext.getLong
|
||||
import pl.szczodrzynski.edziennik.ext.input
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.utils.Colors
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_1_AVG_2_AVG
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_1_AVG_2_SEM
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_1_SEM_2_AVG
|
||||
import pl.szczodrzynski.edziennik.core.manager.GradesManager.Companion.YEAR_ALL_GRADES
|
||||
import timber.log.Timber
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
import kotlin.math.floor
|
||||
|
||||
class GradesEditorFragment : Fragment() {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentGradesEditorBinding
|
||||
/*
|
||||
private val navController: NavController by lazy { Navigation.findNavController(b.root) }
|
||||
*/
|
||||
class GradesEditorFragment : BaseFragment<FragmentGradesEditorBinding, MainActivity>(
|
||||
inflater = FragmentGradesEditorBinding::inflate,
|
||||
) {
|
||||
|
||||
private val config by lazy { app.profile.config.grades }
|
||||
|
||||
@ -61,20 +54,7 @@ class GradesEditorFragment : Fragment() {
|
||||
private var averageMode = YEAR_ALL_GRADES // this means the container should be gone
|
||||
private var yearAverageBefore = 0.0f
|
||||
|
||||
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
|
||||
// activity, context and profile is valid
|
||||
b = FragmentGradesEditorBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded)
|
||||
return
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
subjectId = arguments.getLong("subjectId", -1)
|
||||
semester = arguments.getInt("semester", 1)
|
||||
|
||||
|
@ -5,16 +5,22 @@
|
||||
package pl.szczodrzynski.edziennik.ui.home
|
||||
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.*
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_DRAG
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_IDLE
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.ACTION_STATE_SWIPE
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.DOWN
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.LEFT
|
||||
import androidx.recyclerview.widget.ItemTouchHelper.UP
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import pl.szczodrzynski.edziennik.ui.home.HomeFragment.Companion.removeCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.HomeFragment.Companion.swapCards
|
||||
import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoIndicator
|
||||
|
||||
class CardItemTouchHelperCallback(private val cardAdapter: HomeCardAdapter, private val refreshLayout: SwipeRefreshLayoutNoIndicator?) : ItemTouchHelper.Callback() {
|
||||
class CardItemTouchHelperCallback(
|
||||
private val cardAdapter: HomeCardAdapter,
|
||||
private val onCanRefresh: ((canRefresh: Boolean) -> Unit)?,
|
||||
) : ItemTouchHelper.Callback() {
|
||||
companion object {
|
||||
private const val TAG = "CardItemTouchHelperCallback"
|
||||
private const val DRAG_FLAGS = UP or DOWN
|
||||
private const val SWIPE_FLAGS = LEFT
|
||||
}
|
||||
@ -45,10 +51,10 @@ class CardItemTouchHelperCallback(private val cardAdapter: HomeCardAdapter, priv
|
||||
if (viewHolder != null && (actionState == ACTION_STATE_DRAG || actionState == ACTION_STATE_SWIPE)) {
|
||||
dragCardView = viewHolder.itemView as MaterialCardView
|
||||
dragCardView?.isDragged = true
|
||||
refreshLayout?.isEnabled = false
|
||||
onCanRefresh?.invoke(false)
|
||||
}
|
||||
else if (actionState == ACTION_STATE_IDLE && dragCardView != null) {
|
||||
refreshLayout?.isEnabled = true
|
||||
onCanRefresh?.invoke(true)
|
||||
dragCardView?.isDragged = false
|
||||
dragCardView = null
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BaseDialog
|
||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_EVENTS
|
||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_GRADES
|
||||
import pl.szczodrzynski.edziennik.ui.home.HomeCard.Companion.CARD_LUCKY_NUMBER
|
||||
|
@ -5,22 +5,19 @@
|
||||
package pl.szczodrzynski.edziennik.ui.home
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.View.OnClickListener
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.AccessibilityDelegateCompat
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial.Icon
|
||||
import eu.szkolny.font.SzkolnyFont
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.BuildConfig
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
@ -29,16 +26,22 @@ import pl.szczodrzynski.edziennik.data.enums.FeatureType
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding
|
||||
import pl.szczodrzynski.edziennik.ext.hasUIFeature
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.StudentNumberDialog
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.*
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeArchiveCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeAvailabilityCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeEventsCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeGradesCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeLuckyNumberCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeNotesCard
|
||||
import pl.szczodrzynski.edziennik.ui.home.cards.HomeTimetableCard
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class HomeFragment : Fragment(), CoroutineScope {
|
||||
class HomeFragment : BaseFragment<FragmentHomeBinding, MainActivity>(
|
||||
inflater = FragmentHomeBinding::inflate,
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "HomeFragment"
|
||||
|
||||
fun swapCards(fromPosition: Int, toPosition: Int, cardAdapter: HomeCardAdapter): Boolean {
|
||||
val fromCard = cardAdapter.items[fromPosition]
|
||||
val toCard = cardAdapter.items[toPosition]
|
||||
@ -75,75 +78,58 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentHomeBinding
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_add_remove_cards)
|
||||
.withIcon(Icon.cmd_card_bulleted_settings_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
HomeConfigDialog(activity, reloadOnDismiss = true).show()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_set_student_number)
|
||||
.withIcon(SzkolnyFont.Icon.szf_clipboard_list_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
StudentNumberDialog(activity, app.profile) {
|
||||
app.profileSave()
|
||||
}
|
||||
},
|
||||
BottomSheetSeparatorItem(true),
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_mark_everything_as_read)
|
||||
.withIcon(Icon.cmd_eye_check_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
launch(Dispatchers.IO) {
|
||||
if (!app.data.uiConfig.enableMarkAsReadAnnouncements) {
|
||||
app.db.metadataDao()
|
||||
.setAllSeenExceptMessagesAndAnnouncements(App.profileId, true)
|
||||
} else {
|
||||
app.db.metadataDao().setAllSeenExceptMessages(App.profileId, true)
|
||||
}
|
||||
}
|
||||
|
||||
Toast.makeText(
|
||||
activity,
|
||||
R.string.main_menu_mark_as_read_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
)
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
private val manager
|
||||
get() = app.permissionManager
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = FragmentHomeBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
// TODO check if app, activity, b can be null
|
||||
if (!isAdded)
|
||||
return
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
if (!manager.isNotificationPermissionGranted) {
|
||||
manager.requestNotificationsPermission(activity, 0, false){}
|
||||
}
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_add_remove_cards)
|
||||
.withIcon(Icon.cmd_card_bulleted_settings_outline)
|
||||
.withOnClickListener(OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
HomeConfigDialog(activity, reloadOnDismiss = true).show()
|
||||
}),
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_set_student_number)
|
||||
.withIcon(SzkolnyFont.Icon.szf_clipboard_list_outline)
|
||||
.withOnClickListener(OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
StudentNumberDialog(activity, app.profile) {
|
||||
app.profileSave()
|
||||
}
|
||||
}),
|
||||
BottomSheetSeparatorItem(true),
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_mark_everything_as_read)
|
||||
.withIcon(Icon.cmd_eye_check_outline)
|
||||
.withOnClickListener(OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
launch { withContext(Dispatchers.Default) {
|
||||
if (!app.data.uiConfig.enableMarkAsReadAnnouncements) {
|
||||
app.db.metadataDao().setAllSeenExceptMessagesAndAnnouncements(App.profileId, true)
|
||||
} else {
|
||||
app.db.metadataDao().setAllSeenExceptMessages(App.profileId, true)
|
||||
}
|
||||
} }
|
||||
|
||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||
})
|
||||
)
|
||||
b.configureCards.onClick {
|
||||
HomeConfigDialog(activity, reloadOnDismiss = true).show()
|
||||
}
|
||||
|
||||
b.scrollView.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, _: Int ->
|
||||
b.refreshLayout.isEnabled = scrollY == 0
|
||||
}
|
||||
|
||||
val cards = app.profile.config.ui.homeCards.filter { it.profileId == app.profile.id }.toMutableList()
|
||||
if (cards.isEmpty()) {
|
||||
cards += listOfNotNull(
|
||||
@ -184,7 +170,9 @@ class HomeFragment : Fragment(), CoroutineScope {
|
||||
}
|
||||
|
||||
val adapter = HomeCardAdapter(items)
|
||||
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter, b.refreshLayout))
|
||||
val itemTouchHelper = ItemTouchHelper(CardItemTouchHelperCallback(adapter) {
|
||||
canRefreshDisabled = !it
|
||||
})
|
||||
adapter.itemTouchHelper = itemTouchHelper
|
||||
b.list.layoutManager = LinearLayoutManager(activity)
|
||||
b.list.adapter = adapter
|
||||
|
@ -4,116 +4,49 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.homework
|
||||
|
||||
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 com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import eu.szkolny.font.SzkolnyFont
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Metadata
|
||||
import pl.szczodrzynski.edziennik.data.enums.MetadataType
|
||||
import pl.szczodrzynski.edziennik.databinding.HomeworkFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.databinding.BasePagerFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.addOnPageSelectedListener
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.FragmentLazyPagerAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.PagerFragment
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class HomeworkFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "HomeworkFragment"
|
||||
var pageSelection = 0
|
||||
}
|
||||
class HomeworkFragment : PagerFragment<BasePagerFragmentBinding, MainActivity>(
|
||||
inflater = BasePagerFragmentBinding::inflate,
|
||||
), CoroutineScope {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: HomeworkFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = HomeworkFragmentBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_add_event)
|
||||
.withDescription(R.string.menu_add_event_desc)
|
||||
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
||||
.withOnClickListener(View.OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK).show()
|
||||
}),
|
||||
BottomSheetSeparatorItem(true),
|
||||
override fun getFab() = R.string.add to CommunityMaterial.Icon3.cmd_plus
|
||||
override fun getMarkAsReadType() = MetadataType.HOMEWORK
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
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, MetadataType.HOMEWORK, true) }
|
||||
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
|
||||
}))
|
||||
|
||||
val pagerAdapter = FragmentLazyPagerAdapter(
|
||||
parentFragmentManager,
|
||||
b.refreshLayout,
|
||||
listOf(
|
||||
HomeworkListFragment().apply {
|
||||
arguments = Bundle("homeworkDate" to HomeworkDate.CURRENT)
|
||||
} to getString(R.string.homework_tab_current),
|
||||
|
||||
HomeworkListFragment().apply {
|
||||
arguments = Bundle("homeworkDate" to HomeworkDate.PAST)
|
||||
} to getString(R.string.homework_tab_past)
|
||||
)
|
||||
)
|
||||
b.viewPager.apply {
|
||||
offscreenPageLimit = 1
|
||||
adapter = pagerAdapter
|
||||
currentItem = pageSelection
|
||||
addOnPageSelectedListener {
|
||||
pageSelection = it
|
||||
}
|
||||
b.tabLayout.setupWithViewPager(this)
|
||||
}
|
||||
|
||||
activity.navView.apply {
|
||||
bottomBar.apply {
|
||||
fabEnable = true
|
||||
fabExtendedText = getString(R.string.add)
|
||||
fabIcon = CommunityMaterial.Icon3.cmd_plus
|
||||
}
|
||||
|
||||
setFabOnClickListener(View.OnClickListener {
|
||||
.withTitle(R.string.menu_add_event)
|
||||
.withDescription(R.string.menu_add_event_desc)
|
||||
.withIcon(SzkolnyFont.Icon.szf_calendar_plus_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK).show()
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
activity.gainAttention()
|
||||
activity.gainAttentionFAB()
|
||||
override fun getTabLayout() = b.tabLayout
|
||||
override fun getViewPager() = b.viewPager
|
||||
override suspend fun onCreatePages() = listOf(
|
||||
HomeworkListFragment().apply {
|
||||
arguments = Bundle("homeworkDate" to HomeworkDate.CURRENT)
|
||||
} to getString(R.string.homework_tab_current),
|
||||
HomeworkListFragment().apply {
|
||||
arguments = Bundle("homeworkDate" to HomeworkDate.PAST)
|
||||
} to getString(R.string.homework_tab_past)
|
||||
)
|
||||
|
||||
override suspend fun onFabClick() {
|
||||
EventManualDialog(activity, App.profileId, defaultType = Event.TYPE_HOMEWORK).show()
|
||||
}
|
||||
}
|
||||
|
@ -1,52 +1,28 @@
|
||||
package pl.szczodrzynski.edziennik.ui.homework
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Event
|
||||
import pl.szczodrzynski.edziennik.databinding.HomeworkListFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.getInt
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventDetailsDialog
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventListAdapter
|
||||
import pl.szczodrzynski.edziennik.ui.event.EventManualDialog
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class HomeworkListFragment : LazyFragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "HomeworkListFragment"
|
||||
}
|
||||
class HomeworkListFragment : BaseFragment<HomeworkListFragmentBinding, MainActivity>(
|
||||
inflater = HomeworkListFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: HomeworkListFragmentBinding
|
||||
override fun getRefreshScrollingView() = b.list
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = HomeworkListFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
val homeworkDate = arguments.getInt("homeworkDate", HomeworkDate.CURRENT)
|
||||
|
||||
val today = Date.getToday()
|
||||
@ -87,7 +63,6 @@ class HomeworkListFragment : LazyFragment(), CoroutineScope {
|
||||
}
|
||||
|
||||
// show/hide relevant views
|
||||
setSwipeToRefresh(events.isEmpty())
|
||||
b.progressBar.isVisible = false
|
||||
b.list.isVisible = events.isNotEmpty()
|
||||
b.noData.isVisible = events.isEmpty()
|
||||
@ -104,7 +79,6 @@ class HomeworkListFragment : LazyFragment(), CoroutineScope {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
addOnScrollListener(onScrollListener)
|
||||
this.adapter = adapter
|
||||
}
|
||||
}
|
||||
@ -112,5 +86,5 @@ class HomeworkListFragment : LazyFragment(), CoroutineScope {
|
||||
// reapply the filter
|
||||
adapter.getSearchField()?.applyTo(adapter)
|
||||
})
|
||||
}; return true }
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -19,8 +20,7 @@ import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.LoginStore
|
||||
import pl.szczodrzynski.edziennik.databinding.LoginActivityBinding
|
||||
import pl.szczodrzynski.edziennik.ui.error.ErrorSnackbar
|
||||
import pl.szczodrzynski.edziennik.utils.SwipeRefreshLayoutNoTouch
|
||||
import pl.szczodrzynski.edziennik.ui.main.ErrorSnackbar
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class LoginActivity : AppCompatActivity(), CoroutineScope {
|
||||
@ -34,7 +34,7 @@ class LoginActivity : AppCompatActivity(), CoroutineScope {
|
||||
lateinit var navOptionsBuilder: NavOptions.Builder
|
||||
val nav by lazy { Navigation.findNavController(this, R.id.nav_host_fragment) }
|
||||
val errorSnackbar: ErrorSnackbar by lazy { ErrorSnackbar(this) }
|
||||
val swipeRefreshLayout: SwipeRefreshLayoutNoTouch by lazy { b.swipeRefreshLayout }
|
||||
val swipeRefreshLayout: SwipeRefreshLayout by lazy { b.swipeRefreshLayout }
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2021-3-27.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base
|
||||
package pl.szczodrzynski.edziennik.ui.main
|
||||
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
@ -12,7 +12,6 @@ import com.mikepenz.iconics.utils.colorInt
|
||||
import pl.szczodrzynski.edziennik.databinding.ActivityBuildInvalidBinding
|
||||
import pl.szczodrzynski.edziennik.ext.app
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
|
||||
class BuildInvalidActivity : AppCompatActivity() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package pl.szczodrzynski.edziennik.ui.base
|
||||
package pl.szczodrzynski.edziennik.ui.main
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
@ -21,6 +21,7 @@ import pl.szczodrzynski.edziennik.data.api.szkolny.SzkolnyApi
|
||||
import pl.szczodrzynski.edziennik.data.api.szkolny.request.ErrorReportRequest
|
||||
import pl.szczodrzynski.edziennik.ext.resolveAttr
|
||||
import pl.szczodrzynski.edziennik.ext.resolveColor
|
||||
import pl.szczodrzynski.edziennik.ext.resolveStyleAttr
|
||||
import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
@ -88,7 +89,7 @@ class CrashActivity : AppCompatActivity(), CoroutineScope {
|
||||
|
||||
val moreInfoButton = findViewById<Button>(R.id.crash_details_btn)
|
||||
moreInfoButton.setOnClickListener {
|
||||
MaterialAlertDialogBuilder(this, R.attr.materialAlertDialogMonospaceTheme.resolveAttr(this))
|
||||
MaterialAlertDialogBuilder(this, R.attr.materialAlertDialogMonospaceTheme.resolveStyleAttr(this))
|
||||
.setTitle(R.string.crash_details)
|
||||
.setMessage(BetterHtml.fromHtml(context = null, getErrorString(intent, false)))
|
||||
.setPositiveButton(R.string.close, null)
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-13.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.error
|
||||
package pl.szczodrzynski.edziennik.ui.main
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -14,6 +14,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.ErrorDetailsDialog
|
||||
import pl.szczodrzynski.navlib.getColorFromAttr
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-12-22.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.base
|
||||
package pl.szczodrzynski.edziennik.ui.main
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
@ -6,22 +6,27 @@ package pl.szczodrzynski.edziennik.ui.messages.compose
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AutoCompleteTextView
|
||||
import android.widget.ScrollView
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.core.manager.MessageManager.UIConfig
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.COMPATIBLE
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.ORIGINAL
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.StylingConfig
|
||||
import pl.szczodrzynski.edziennik.data.api.ERROR_MESSAGE_NOT_SENT
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageSentEvent
|
||||
@ -30,33 +35,49 @@ import pl.szczodrzynski.edziennik.data.api.models.ApiError
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.enums.LoginType
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesComposeFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.DAY
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.MessagesConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
||||
import pl.szczodrzynski.edziennik.utils.DefaultTextStyles
|
||||
import pl.szczodrzynski.edziennik.core.manager.MessageManager.UIConfig
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.COMPATIBLE
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode.ORIGINAL
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.StylingConfig
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
class MessagesComposeFragment : BaseFragment<MessagesComposeFragmentBinding, MainActivity>(
|
||||
inflater = MessagesComposeFragmentBinding::inflate,
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "MessagesComposeFragment"
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: MessagesComposeFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
override fun getFab() = R.string.messages_compose_send to CommunityMaterial.Icon3.cmd_send_outline
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.messages_compose_send_long)
|
||||
.withIcon(CommunityMaterial.Icon3.cmd_send_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
sendMessage()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.messages_compose_save_draft)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_content_save_edit_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
saveDraft()
|
||||
},
|
||||
BottomSheetSeparatorItem(true),
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_messages_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
MessagesConfigDialog(activity, false, null, null).show()
|
||||
}
|
||||
)
|
||||
|
||||
private val manager
|
||||
get() = app.messageManager
|
||||
@ -75,25 +96,7 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
private var discardDraftItem: BottomSheetPrimaryItem? = null
|
||||
private var draftMessageId: Long? = null
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
// activity, context and profile is valid
|
||||
b = MessagesComposeFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
override fun onDestroy() {
|
||||
EventBus.getDefault().unregister(this)
|
||||
super.onDestroy()
|
||||
}
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
// TODO check if app, activity, b can be null
|
||||
if (!isAdded)
|
||||
return
|
||||
|
||||
EventBus.getDefault().register(this)
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
b.breakpoints.visibility = if (App.devMode) View.VISIBLE else View.GONE
|
||||
b.breakpoints.setOnClickListener {
|
||||
b.breakpoints.isEnabled = true
|
||||
@ -110,37 +113,8 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
discardDraftDialog()
|
||||
}
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.messages_compose_send_long)
|
||||
.withIcon(CommunityMaterial.Icon3.cmd_send_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
sendMessage()
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.messages_compose_save_draft)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_content_save_edit_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
saveDraft()
|
||||
},
|
||||
BottomSheetSeparatorItem(true),
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_messages_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
MessagesConfigDialog(activity, false, null, null).show()
|
||||
}
|
||||
)
|
||||
|
||||
launch {
|
||||
delay(100)
|
||||
getRecipientList()
|
||||
|
||||
createView()
|
||||
}
|
||||
getRecipientList()
|
||||
createView()
|
||||
}
|
||||
|
||||
private fun getMessageBody(): String {
|
||||
@ -150,18 +124,16 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
b.text.text?.toString() ?: ""
|
||||
}
|
||||
|
||||
private fun getRecipientList() {
|
||||
private suspend fun getRecipientList() {
|
||||
if (app.data.messagesConfig.syncRecipientList && System.currentTimeMillis() - app.profile.lastReceiversSync > 1 * DAY * 1000) {
|
||||
activity.snackbar("Pobieranie listy odbiorców...")
|
||||
EdziennikTask.recipientListGet(App.profileId).enqueue(activity)
|
||||
}
|
||||
else {
|
||||
launch {
|
||||
val list = withContext(Dispatchers.Default) {
|
||||
app.db.teacherDao().getAllNow(App.profileId).filter { it.loginId != null }
|
||||
}
|
||||
updateRecipientList(list)
|
||||
val list = withContext(Dispatchers.IO) {
|
||||
app.db.teacherDao().getAllNow(App.profileId).filter { it.loginId != null }
|
||||
}
|
||||
updateRecipientList(list)
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,18 +231,10 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
changedBody = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activity.navView.bottomBar.apply {
|
||||
fabEnable = true
|
||||
fabExtendedText = getString(R.string.messages_compose_send)
|
||||
fabIcon = CommunityMaterial.Icon3.cmd_send_outline
|
||||
|
||||
setFabOnClickListener {
|
||||
sendMessage()
|
||||
}
|
||||
}
|
||||
|
||||
activity.gainAttentionFAB()
|
||||
override suspend fun onFabClick() {
|
||||
sendMessage()
|
||||
}
|
||||
|
||||
private fun onBeforeNavigate(): Boolean {
|
||||
@ -437,15 +401,13 @@ class MessagesComposeFragment : Fragment(), CoroutineScope {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (!isAdded || !this::activity.isInitialized)
|
||||
if (!isAdded)
|
||||
return
|
||||
activity.onBeforeNavigate = this::onBeforeNavigate
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (!this::activity.isInitialized)
|
||||
return
|
||||
activity.onBeforeNavigate = null
|
||||
}
|
||||
|
||||
|
@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2020-4-4.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.messages.compose
|
||||
|
||||
class MessagesComposeInfo(
|
||||
/**
|
||||
* 0 means no attachments.
|
||||
* -1 means unlimited number.
|
||||
*/
|
||||
@JvmField var maxAttachmentNumber: Int,
|
||||
/**
|
||||
* -1 means unlimited size.
|
||||
*/
|
||||
var attachmentSizeLimit: Long,
|
||||
/**
|
||||
* -1 means unlimited length.
|
||||
*/
|
||||
var maxSubjectLength: Int,
|
||||
/**
|
||||
* -1 means unlimited length.
|
||||
*/
|
||||
var maxBodyLength: Int
|
||||
)
|
@ -1,144 +1,72 @@
|
||||
package pl.szczodrzynski.edziennik.ui.messages.list
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.addOnPageSelectedListener
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.FragmentLazyPagerAdapter
|
||||
import pl.szczodrzynski.edziennik.databinding.BasePagerFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.PagerFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.MessagesConfigDialog
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MessagesFragment : Fragment(), CoroutineScope {
|
||||
class MessagesFragment : PagerFragment<BasePagerFragmentBinding, MainActivity>(
|
||||
inflater = BasePagerFragmentBinding::inflate,
|
||||
) {
|
||||
companion object {
|
||||
private const val TAG = "MessagesFragment"
|
||||
var pageSelection = 0
|
||||
}
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: MessagesFragmentBinding
|
||||
override fun getFab() = R.string.compose to CommunityMaterial.Icon3.cmd_pencil_outline
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_message_compose)
|
||||
.withIcon(CommunityMaterial.Icon3.cmd_pencil_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
activity.navigate(navTarget = NavTarget.MESSAGE_COMPOSE)
|
||||
},
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_messages_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
MessagesConfigDialog(activity, false, null, null).show()
|
||||
}
|
||||
)
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = MessagesFragmentBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
override fun getTabLayout() = b.tabLayout
|
||||
override fun getViewPager() = b.viewPager
|
||||
override suspend fun onCreatePages() = listOf(
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_RECEIVED)
|
||||
} to getString(R.string.messages_tab_received),
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_SENT)
|
||||
} to getString(R.string.messages_tab_sent),
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_DELETED)
|
||||
} to getString(R.string.messages_tab_deleted),
|
||||
MessagesListFragment().apply {
|
||||
arguments = Bundle("messageType" to Message.TYPE_DRAFT)
|
||||
} to getString(R.string.messages_tab_draft),
|
||||
)
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
val messageId = arguments?.getLong("messageId", -1L) ?: -1L
|
||||
if (messageId != -1L) {
|
||||
val args = Bundle()
|
||||
args.putLong("messageId", messageId)
|
||||
arguments?.remove("messageId")
|
||||
activity.navigate(navTarget = NavTarget.MESSAGE, args = args)
|
||||
return
|
||||
}
|
||||
|
||||
val args = arguments
|
||||
|
||||
val pagerAdapter = FragmentLazyPagerAdapter(
|
||||
fragmentManager = parentFragmentManager,
|
||||
swipeRefreshLayout = b.refreshLayout,
|
||||
fragments = listOf(
|
||||
MessagesListFragment().apply {
|
||||
onPageDestroy = this@MessagesFragment.onPageDestroy
|
||||
arguments = Bundle("messageType" to Message.TYPE_RECEIVED)
|
||||
args?.getBundle("page0")?.let {
|
||||
arguments?.putAll(it)
|
||||
}
|
||||
} to getString(R.string.messages_tab_received),
|
||||
|
||||
MessagesListFragment().apply {
|
||||
onPageDestroy = this@MessagesFragment.onPageDestroy
|
||||
arguments = Bundle("messageType" to Message.TYPE_SENT)
|
||||
args?.getBundle("page1")?.let {
|
||||
arguments?.putAll(it)
|
||||
}
|
||||
} to getString(R.string.messages_tab_sent),
|
||||
|
||||
MessagesListFragment().apply {
|
||||
onPageDestroy = this@MessagesFragment.onPageDestroy
|
||||
arguments = Bundle("messageType" to Message.TYPE_DELETED)
|
||||
args?.getBundle("page2")?.let {
|
||||
arguments?.putAll(it)
|
||||
}
|
||||
} to getString(R.string.messages_tab_deleted),
|
||||
|
||||
MessagesListFragment().apply {
|
||||
onPageDestroy = this@MessagesFragment.onPageDestroy
|
||||
arguments = Bundle("messageType" to Message.TYPE_DRAFT)
|
||||
args?.getBundle("page3")?.let {
|
||||
arguments?.putAll(it)
|
||||
}
|
||||
} to getString(R.string.messages_tab_draft),
|
||||
),
|
||||
)
|
||||
b.viewPager.apply {
|
||||
offscreenPageLimit = 1
|
||||
adapter = pagerAdapter
|
||||
currentItem = pageSelection
|
||||
addOnPageSelectedListener {
|
||||
pageSelection = it
|
||||
}
|
||||
b.tabLayout.setupWithViewPager(this)
|
||||
}
|
||||
|
||||
activity.navView.apply {
|
||||
bottomBar.apply {
|
||||
fabEnable = true
|
||||
fabExtendedText = getString(R.string.compose)
|
||||
fabIcon = CommunityMaterial.Icon3.cmd_pencil_outline
|
||||
}
|
||||
|
||||
bottomSheet.prependItem(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_messages_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
MessagesConfigDialog(activity, false, null, null).show()
|
||||
}
|
||||
)
|
||||
|
||||
setFabOnClickListener {
|
||||
activity.navigate(navTarget = NavTarget.MESSAGE_COMPOSE)
|
||||
}
|
||||
}
|
||||
|
||||
activity.gainAttentionFAB()
|
||||
super.onViewReady(savedInstanceState)
|
||||
}
|
||||
|
||||
private val onPageDestroy = { position: Int, outState: Bundle? ->
|
||||
arguments?.putBundle("page$position", outState)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
(b.viewPager.adapter as? FragmentLazyPagerAdapter)?.fragments?.forEach {
|
||||
it.first.onDestroy()
|
||||
}
|
||||
override suspend fun onFabClick() {
|
||||
activity.navigate(navTarget = NavTarget.MESSAGE_COMPOSE)
|
||||
}
|
||||
}
|
||||
|
@ -4,58 +4,42 @@
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.messages.list
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import kotlinx.coroutines.*
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Message
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Teacher
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.databinding.MessagesListFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.getInt
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.ui.base.lazypager.LazyFragment
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "MessagesListFragment"
|
||||
}
|
||||
class MessagesListFragment : BaseFragment<MessagesListFragmentBinding, MainActivity>(
|
||||
inflater = MessagesListFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
override fun getRefreshScrollingView() = b.list
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: MessagesListFragmentBinding
|
||||
private lateinit var adapter: MessagesAdapter
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
// local/private variables go here
|
||||
private val manager
|
||||
get() = app.messageManager
|
||||
var teachers = listOf<Teacher>()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = MessagesListFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onPageCreated(): Boolean { startCoroutineTimer(100L) {
|
||||
@SuppressLint("RestrictedApi")
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
val messageType = arguments.getInt("messageType", Message.TYPE_RECEIVED)
|
||||
var recyclerViewState =
|
||||
arguments?.getParcelable<LinearLayoutManager.SavedState>("recyclerViewState")
|
||||
val searchText = arguments?.getString("searchText")
|
||||
savedInstanceState?.getParcelable<LinearLayoutManager.SavedState>("recyclerViewState")
|
||||
val searchText = savedInstanceState?.getString("searchText")
|
||||
|
||||
teachers = withContext(Dispatchers.Default) {
|
||||
app.db.teacherDao().getAllNow(App.profileId)
|
||||
@ -91,8 +75,10 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
}
|
||||
}
|
||||
|
||||
if (messageType != Message.TYPE_RECEIVED && messageType != Message.TYPE_SENT)
|
||||
canRefreshDisabled = true
|
||||
|
||||
// show/hide relevant views
|
||||
setSwipeToRefresh(messageType in Message.TYPE_RECEIVED..Message.TYPE_SENT)
|
||||
b.progressBar.isVisible = false
|
||||
b.list.isVisible = messages.isNotEmpty()
|
||||
b.noData.isVisible = messages.isEmpty()
|
||||
@ -109,8 +95,6 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
if (messageType in Message.TYPE_RECEIVED..Message.TYPE_SENT)
|
||||
addOnScrollListener(onScrollListener)
|
||||
this.adapter = this@MessagesListFragment.adapter
|
||||
}
|
||||
}
|
||||
@ -126,18 +110,15 @@ class MessagesListFragment : LazyFragment(), CoroutineScope {
|
||||
recyclerViewState = null
|
||||
}
|
||||
})
|
||||
}; return true }
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
if (!isAdded || !this::adapter.isInitialized)
|
||||
return
|
||||
val layoutManager = (b.list.layoutManager as? LinearLayoutManager)
|
||||
val searchField = adapter.getSearchField()
|
||||
|
||||
onPageDestroy?.invoke(position, Bundle(
|
||||
"recyclerViewState" to layoutManager?.onSaveInstanceState(),
|
||||
"searchText" to searchField?.searchText?.toString()
|
||||
))
|
||||
outState.putParcelable("recyclerViewState", layoutManager?.onSaveInstanceState())
|
||||
outState.putString("searchText", searchField?.searchText?.toString())
|
||||
}
|
||||
}
|
||||
|
@ -5,28 +5,30 @@
|
||||
package pl.szczodrzynski.edziennik.ui.messages.single
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.mikepenz.iconics.IconicsDrawable
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import com.mikepenz.iconics.utils.sizeDp
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.launch
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
import org.greenrobot.eventbus.ThreadMode
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.api.edziennik.EdziennikTask
|
||||
import pl.szczodrzynski.edziennik.data.api.events.MessageGetEvent
|
||||
import pl.szczodrzynski.edziennik.data.enums.LoginType
|
||||
import pl.szczodrzynski.edziennik.data.db.full.MessageFull
|
||||
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.data.enums.LoginType
|
||||
import pl.szczodrzynski.edziennik.data.enums.NavTarget
|
||||
import pl.szczodrzynski.edziennik.databinding.MessageFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.Bundle
|
||||
import pl.szczodrzynski.edziennik.ext.attachToastHint
|
||||
import pl.szczodrzynski.edziennik.ext.get
|
||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
|
||||
import pl.szczodrzynski.edziennik.ext.onClick
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.MessagesConfigDialog
|
||||
import pl.szczodrzynski.edziennik.ui.messages.MessagesUtils
|
||||
import pl.szczodrzynski.edziennik.ui.messages.list.MessagesFragment
|
||||
@ -37,48 +39,27 @@ import pl.szczodrzynski.edziennik.utils.html.BetterHtml
|
||||
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.colorAttr
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.math.min
|
||||
|
||||
class MessageFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "MessageFragment"
|
||||
}
|
||||
class MessageFragment : BaseFragment<MessageFragmentBinding, MainActivity>(
|
||||
inflater = MessageFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: MessageFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_messages_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
MessagesConfigDialog(activity, false, null, null).show()
|
||||
}
|
||||
)
|
||||
|
||||
private val manager
|
||||
get() = app.messageManager
|
||||
private lateinit var message: MessageFull
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = MessageFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
|
||||
activity.bottomSheet.prependItem(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_messages_config)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_cog_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
MessagesConfigDialog(activity, false, null, null).show()
|
||||
}
|
||||
)
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
b.closeButton.onClick { activity.navigateUp() }
|
||||
|
||||
// click to expand subject and sender
|
||||
@ -88,7 +69,6 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
b.senderContainer.onClick {
|
||||
b.sender.maxLines = if (b.sender.maxLines == 30) 2 else 30
|
||||
}
|
||||
// TODO bring back iconics to reply/forward buttons - add modern icons to SzkolnyFont
|
||||
|
||||
b.messageStar.onClick {
|
||||
launch {
|
||||
@ -129,14 +109,12 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
EdziennikTask.messageGet(App.profileId, message).enqueue(activity)
|
||||
}
|
||||
|
||||
launch {
|
||||
message = manager.getMessage(App.profileId, arguments) ?: run {
|
||||
activity.navigateUp()
|
||||
return@launch
|
||||
}
|
||||
b.subject.text = message.subject
|
||||
checkMessage()
|
||||
message = manager.getMessage(App.profileId, arguments) ?: run {
|
||||
activity.navigateUp()
|
||||
return
|
||||
}
|
||||
b.subject.text = message.subject
|
||||
checkMessage()
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
|
||||
@ -253,17 +231,4 @@ class MessageFragment : Fragment(), CoroutineScope {
|
||||
}, owner = message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
EventBus.getDefault().register(this)
|
||||
super.onStart()
|
||||
}
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
EventBus.getDefault().unregister(this)
|
||||
}
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
job.cancel()
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Note
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Noteable
|
||||
import pl.szczodrzynski.edziennik.databinding.NoteDetailsDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.*
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
|
||||
class NoteDetailsDialog(
|
||||
|
@ -21,7 +21,7 @@ import pl.szczodrzynski.edziennik.data.db.entity.Profile
|
||||
import pl.szczodrzynski.edziennik.databinding.NoteEditorDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorBlank
|
||||
import pl.szczodrzynski.edziennik.ext.resolveString
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.settings.RegistrationConfigDialog
|
||||
import pl.szczodrzynski.edziennik.utils.TextInputDropDown
|
||||
import pl.szczodrzynski.edziennik.core.manager.TextStylingManager.HtmlMode
|
||||
|
@ -11,7 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Noteable
|
||||
import pl.szczodrzynski.edziennik.databinding.NoteListDialogBinding
|
||||
import pl.szczodrzynski.edziennik.ui.dialogs.base.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.ui.base.dialog.BindingDialog
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
|
||||
class NoteListDialog(
|
||||
|
@ -5,99 +5,32 @@
|
||||
package pl.szczodrzynski.edziennik.ui.notes
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Note
|
||||
import pl.szczodrzynski.edziennik.data.db.entity.Noteable
|
||||
import pl.szczodrzynski.edziennik.databinding.NotesFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class NotesFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "NotesFragment"
|
||||
}
|
||||
class NotesFragment : BaseFragment<NotesFragmentBinding, MainActivity>(
|
||||
inflater = NotesFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: NotesFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
override fun getFab() =
|
||||
R.string.notes_action_add to CommunityMaterial.Icon3.cmd_text_box_plus_outline
|
||||
|
||||
private val manager
|
||||
get() = app.noteManager
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?,
|
||||
): View? {
|
||||
activity = getActivity() as? MainActivity ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = NotesFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
private fun onNoteClick(note: Note) = launch {
|
||||
val owner = withContext(Dispatchers.IO) {
|
||||
manager.getOwner(note)
|
||||
} as? Noteable
|
||||
|
||||
NoteDetailsDialog(
|
||||
activity = activity,
|
||||
owner = owner,
|
||||
note = note,
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun onNoteEditClick(note: Note) = launch {
|
||||
val owner = withContext(Dispatchers.IO) {
|
||||
manager.getOwner(note)
|
||||
} as? Noteable
|
||||
|
||||
NoteEditorDialog(
|
||||
activity = activity,
|
||||
owner = owner,
|
||||
editingNote = note,
|
||||
profileId = App.profileId,
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun onNoteAddClick(view: View?) {
|
||||
NoteEditorDialog(
|
||||
activity = activity,
|
||||
owner = null,
|
||||
editingNote = null,
|
||||
profileId = App.profileId,
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (!isAdded) return
|
||||
|
||||
activity.navView.apply {
|
||||
bottomBar.apply {
|
||||
fabEnable = true
|
||||
fabExtendedText = getString(R.string.notes_action_add)
|
||||
fabIcon = CommunityMaterial.Icon3.cmd_text_box_plus_outline
|
||||
}
|
||||
|
||||
setFabOnClickListener(this@NotesFragment::onNoteAddClick)
|
||||
}
|
||||
activity.gainAttentionFAB()
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
val adapter = NoteListAdapter(
|
||||
activity = activity,
|
||||
onNoteClick = this::onNoteClick,
|
||||
@ -153,4 +86,38 @@ class NotesFragment : Fragment(), CoroutineScope {
|
||||
adapter.getSearchField()?.applyTo(adapter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNoteClick(note: Note) = launch {
|
||||
val owner = withContext(Dispatchers.IO) {
|
||||
manager.getOwner(note)
|
||||
} as? Noteable
|
||||
|
||||
NoteDetailsDialog(
|
||||
activity = activity,
|
||||
owner = owner,
|
||||
note = note,
|
||||
).show()
|
||||
}
|
||||
|
||||
private fun onNoteEditClick(note: Note) = launch {
|
||||
val owner = withContext(Dispatchers.IO) {
|
||||
manager.getOwner(note)
|
||||
} as? Noteable
|
||||
|
||||
NoteEditorDialog(
|
||||
activity = activity,
|
||||
owner = owner,
|
||||
editingNote = note,
|
||||
profileId = App.profileId,
|
||||
).show()
|
||||
}
|
||||
|
||||
override suspend fun onFabClick() {
|
||||
NoteEditorDialog(
|
||||
activity = activity,
|
||||
owner = null,
|
||||
editingNote = null,
|
||||
profileId = App.profileId,
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
@ -6,64 +6,45 @@ package pl.szczodrzynski.edziennik.ui.notifications
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
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.core.view.isVisible
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import kotlinx.coroutines.launch
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.R
|
||||
import pl.szczodrzynski.edziennik.databinding.NotificationsListFragmentBinding
|
||||
import pl.szczodrzynski.edziennik.ext.isNotNullNorEmpty
|
||||
import pl.szczodrzynski.edziennik.ext.startCoroutineTimer
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import pl.szczodrzynski.edziennik.utils.Utils
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
import timber.log.Timber
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
class NotificationsListFragment : Fragment(), CoroutineScope {
|
||||
companion object {
|
||||
private const val TAG = "NotificationsListFragment"
|
||||
}
|
||||
class NotificationsListFragment : BaseFragment<NotificationsListFragmentBinding, MainActivity>(
|
||||
inflater = NotificationsListFragmentBinding::inflate,
|
||||
) {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: NotificationsListFragmentBinding
|
||||
|
||||
private val job: Job = Job()
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = job + Dispatchers.Main
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
activity = (getActivity() as MainActivity?) ?: return null
|
||||
context ?: return null
|
||||
app = activity.application as App
|
||||
b = NotificationsListFragmentBinding.inflate(inflater)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { startCoroutineTimer(100L) {
|
||||
if (!isAdded) return@startCoroutineTimer
|
||||
|
||||
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()
|
||||
}))
|
||||
override fun getBottomSheetItems() = listOf(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_remove_notifications)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_delete_sweep_outline)
|
||||
.withOnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
launch(Dispatchers.IO) {
|
||||
app.db.notificationDao().clearAll()
|
||||
}
|
||||
Toast.makeText(
|
||||
activity,
|
||||
R.string.menu_remove_notifications_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
)
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
val adapter = NotificationsAdapter(activity) { notification ->
|
||||
val intent = Intent("android.intent.action.MAIN")
|
||||
notification.fillIntent(intent)
|
||||
@ -100,5 +81,5 @@ class NotificationsListFragment : Fragment(), CoroutineScope {
|
||||
b.noData.isVisible = false
|
||||
}
|
||||
})
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,14 @@
|
||||
package pl.szczodrzynski.edziennik.ui.settings
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import pl.szczodrzynski.edziennik.App
|
||||
import pl.szczodrzynski.edziennik.MainActivity
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentProfileManagerBinding
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
|
||||
class ProfileManagerFragment : Fragment() {
|
||||
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentProfileManagerBinding
|
||||
/*
|
||||
private val navController: NavController by lazy { Navigation.findNavController(b.root) }
|
||||
*/
|
||||
|
||||
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
|
||||
// activity, context and profile is valid
|
||||
b = FragmentProfileManagerBinding.inflate(inflater)
|
||||
b.refreshLayout.setParent(activity.swipeRefreshLayout)
|
||||
return b.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
if (app.profile == null || !isAdded)
|
||||
return
|
||||
import pl.szczodrzynski.edziennik.ui.base.fragment.BaseFragment
|
||||
|
||||
class ProfileManagerFragment : BaseFragment<FragmentProfileManagerBinding, MainActivity>(
|
||||
inflater = FragmentProfileManagerBinding::inflate,
|
||||
) {
|
||||
|
||||
override suspend fun onViewReady(savedInstanceState: Bundle?) {
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user