Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ build/
# Local configuration file (sdk path, etc)
local.properties

# Release folders
app/release

# Log/OS Files
*.log

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class TokenManager(private val context: Context) {
suspend fun clearSession() {
context.dataStore.edit { preferences ->
preferences.remove(KEY_AUTH_TOKEN)
// Optional: Keep the URL so they don't have to retype it
preferences.remove(KEY_LAST_DESCRIPTION)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package net.ardevd.tagius.features.records.ui.list

import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModel
Expand All @@ -20,12 +25,14 @@ import net.ardevd.tagius.core.data.TokenManager
import net.ardevd.tagius.core.network.RetrofitClient
import net.ardevd.tagius.core.utils.DateRanges
import net.ardevd.tagius.databinding.FragmentRecordsListBinding
import net.ardevd.tagius.features.auth.ui.LoginFragment
import net.ardevd.tagius.features.records.data.RecordsRepository
import net.ardevd.tagius.features.records.ui.add.AddRecordBottomSheet
import net.ardevd.tagius.features.records.ui.edit.EditRecordBottomSheet
import net.ardevd.tagius.features.records.viewmodel.RecordsUiState
import net.ardevd.tagius.features.records.viewmodel.RecordsViewModel
import net.ardevd.tagius.features.records.viewmodel.RecordsViewModelFactory
import net.ardevd.tagius.features.settings.ui.SettingsBottomSheet

class RecordsListFragment : Fragment(R.layout.fragment_records_list) {

Expand Down Expand Up @@ -103,6 +110,53 @@ class RecordsListFragment : Fragment(R.layout.fragment_records_list) {
}

setupFilterChips()

setupMenu()
}

private fun setupMenu() {
val menuHost = requireActivity()

menuHost.addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.menu_records_list, menu)
}

override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
return when (menuItem.itemId) {
R.id.action_settings -> {
showSettingsSheet()
true
}
else -> false
}
}
}, viewLifecycleOwner, Lifecycle.State.RESUMED)
}

private fun showSettingsSheet() {
val sheet = SettingsBottomSheet {
performLogout()
}
sheet.show(parentFragmentManager, SettingsBottomSheet.TAG)
}

private fun performLogout() {
viewLifecycleOwner.lifecycleScope.launch {
TokenManager(requireContext()).clearSession()

RetrofitClient.reset()

// We use popBackStack to clear the history so "Back" doesn't return here
parentFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)

parentFragmentManager.beginTransaction()
.replace(R.id.fragment_container, LoginFragment())
.commit()

// Hide Toolbar (since Login shouldn't show it)
requireActivity().findViewById<View>(R.id.topAppBar).isVisible = false
}
}

private fun setupRecyclerView() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.ardevd.tagius.features.settings.ui

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import net.ardevd.tagius.core.data.TokenManager
import net.ardevd.tagius.databinding.FragmentSettingsBinding

class SettingsBottomSheet(
private val onLogout: () -> Unit
) : BottomSheetDialogFragment() {

private var _binding: FragmentSettingsBinding? = null
private val binding get() = _binding!!

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentSettingsBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

// Display the stored URL so the user knows which server they are on
viewLifecycleOwner.lifecycleScope.launch {
val url = TokenManager(requireContext()).serverUrlFlow.first()
binding.serverUrlText.text = url
}

// Handle Logout
binding.logoutButton.setOnClickListener {
dismiss()
onLogout()
}
}

companion object {
const val TAG = "SettingsBottomSheet"
}
}
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_logout.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M538,422L538,422Q538,422 538,422Q538,422 538,422Q538,422 538,422Q538,422 538,422Q538,422 538,422Q538,422 538,422ZM424,536Q424,536 424,536Q424,536 424,536L424,536Q424,536 424,536Q424,536 424,536Q424,536 424,536Q424,536 424,536ZM480,800Q531,800 578,784.5Q625,769 666,740Q625,711 578,695.5Q531,680 480,680Q429,680 382,695.5Q335,711 294,740Q335,769 382,784.5Q429,800 480,800ZM586,472L529,415Q534,407 537,398Q540,389 540,380Q540,355 522.5,337.5Q505,320 480,320Q471,320 462,323Q453,326 445,331L388,274Q407,257 430.5,248.5Q454,240 480,240Q538,240 579,281Q620,322 620,380Q620,406 611.5,429.5Q603,453 586,472ZM814,700L756,642Q778,605 789,564Q800,523 800,480Q800,346 707,253Q614,160 480,160Q437,160 396,171Q355,182 318,204L260,146Q309,114 365,97Q421,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,539 863,595Q846,651 814,700ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,421 96.5,365Q113,309 145,259L27,140L84,83L876,875L819,932L204,318Q182,355 171,396Q160,437 160,480Q160,537 179,589Q198,641 234,684Q288,643 350.5,621.5Q413,600 480,600Q518,600 556,608Q594,616 630,630L763,763Q706,820 633,850Q560,880 480,880Z"/>

</vector>
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/ic_settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="960" android:viewportWidth="960" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M620,676L676,620Q682,614 682,606Q682,598 676,592L540,455Q544,444 546,433Q548,422 548,408Q548,351 507.5,310.5Q467,270 410,270Q393,270 376,274.5Q359,279 343,287L437,381L381,437L287,343Q279,359 274.5,376Q270,393 270,410Q270,467 310.5,507.5Q351,548 408,548Q421,548 432.5,546Q444,544 455,540L592,676Q598,682 606,682Q614,682 620,676ZM480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880ZM480,800Q614,800 707,707Q800,614 800,480Q800,346 707,253Q614,160 480,160Q346,160 253,253Q160,346 160,480Q160,614 253,707Q346,800 480,800ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>

</vector>
73 changes: 73 additions & 0 deletions app/src/main/res/layout/fragment_settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="32dp">

<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/dragHandle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_account_settings"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
android:layout_marginStart="24dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/dragHandle" />

<com.google.android.material.card.MaterialCardView
android:id="@+id/serverCard"
style="@style/Widget.Material3.CardView.Filled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="24dp"
app:cardBackgroundColor="?attr/colorSurfaceContainer"
app:layout_constraintTop_toBottomOf="@id/title">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_connected_to"
android:textAppearance="?attr/textAppearanceLabelMedium"
android:textColor="?attr/colorOnSurfaceVariant" />

<TextView
android:id="@+id/serverUrlText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="https://timetagger.app"
android:textAppearance="?attr/textAppearanceBodyLarge"
android:textStyle="bold"
android:layout_marginTop="4dp"
android:ellipsize="end"
android:maxLines="1" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

<com.google.android.material.button.MaterialButton
android:id="@+id/logoutButton"
style="@style/Widget.Material3.Button.TonalButton"
android:layout_width="match_parent"
android:layout_height="56dp"
android:layout_marginHorizontal="24dp"
android:layout_marginTop="32dp"
android:text="@string/settings_log_out"
app:icon="@drawable/ic_logout"
app:layout_constraintTop_toBottomOf="@id/serverCard"
app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
11 changes: 11 additions & 0 deletions app/src/main/res/menu/menu_records_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<item
android:id="@+id/action_settings"
android:contentDescription="@string/settings_account_settings"
android:icon="@drawable/ic_settings"
android:title="@string/settings_settings"
app:showAsAction="ifRoom" />
</menu>
4 changes: 4 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@
<string name="cd_start_new_timer">Start a new timer</string>
<string name="cd_range_filter">Time range filter options</string>

<string name="settings_account_settings">Account Settings</string>
<string name="settings_connected_to">Connected to</string>
<string name="settings_log_out">Log Out</string>
<string name="settings_settings">Settings</string>
</resources>
Loading