Ajout de deux packages pour une liste de Sessions et une liste d’Attendances.

Pourra changer dans le futur
Correction du code pour qu’il puisse compiler.
This commit is contained in:
biloute02 2023-12-22 11:01:03 +01:00
parent a856513920
commit 1c04f18ec8
24 changed files with 368 additions and 144 deletions

View file

@ -8,7 +8,7 @@ import java.io.IOException
* Class that handles authentication w/ login credentials and retrieves user information.
*/
class LocalDataSource {
/*
fun login(username: String, password: String): Result<LoggedInUser> {
try {
@ -24,4 +24,5 @@ class LocalDataSource {
fun logout() {
// TODO: revoke authentication
}
*/
}

View file

@ -0,0 +1,10 @@
package com.example.palto.data.model
import java.io.Serializable
/**
* Data class that captures tokens for logged in users retrieved from LoginRepository
*/
data class Attendance(
val date: String,
val access: String
) : Serializable

View file

@ -0,0 +1,9 @@
package com.example.palto.data.model
import java.io.Serializable
/**
* Data class that captures tokens for logged in users retrieved from LoginRepository
*/
data class StudentCard(
val id: String
) : Serializable

View file

@ -12,36 +12,48 @@ class ServerDataSource {
private var hostname: String? = null
fun requestToken(hostname: String, username: String, password: String): Result<Tokens> {
fun requestToken(
hostname: String,
username: String,
password: String
): Result<Tokens> {
try {
val tokens = Tokens()
return Result.Success()
} catch () {
return Result.Error()
}
}
fun refreshToken(): Result<Tokens> {
}
fun verifyToken(): Boolean {
}
fun login(hostname: String, username: String, password: String): Result<LoggedInUser> {
try {
/*
val fakeUser = LoggedInUser(java.util.UUID.randomUUID().toString(), "Jane Doe")
return Result.Success(fakeUser)
*/
return
val tokens = Tokens(
refresh = "aa",
access = "bb"
)
return Result.Success(tokens)
} catch (e: Throwable) {
return Result.Error(IOException("Error logging in", e))
}
}
fun logout() {
// TODO: revoke authentication
fun refreshToken(current_tokens: Tokens): Result<Tokens> {
return Result.Success(current_tokens)
}
fun verifyToken(): Boolean {
return true
}
fun login(
hostname: String,
username: String,
password: String
): Result<LoggedInUser> {
try {
val fakeUser = LoggedInUser(
java.util.UUID.randomUUID().toString(),
"dede",
"Lucie",
"Doe",
"aa@free.fr",
)
return Result.Success(fakeUser)
} catch (e: Throwable) {
return Result.Error(IOException("Error logging in", e))
}
}
fun logout() { }
}

View file

@ -0,0 +1,13 @@
package com.example.palto.data.repository
import com.example.palto.data.Result
import com.example.palto.data.network.ServerDataSource
import com.example.palto.data.model.LoggedInUser
import com.example.palto.data.model.Tokens
/**
*
*/
class AttendanceRepository(val dataSource: ServerDataSource) {
// private val cards
}

View file

@ -19,8 +19,6 @@ class LoginRepository(val dataSource: ServerDataSource) {
get() = user != null
init {
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
user = null
}
@ -38,7 +36,7 @@ class LoginRepository(val dataSource: ServerDataSource) {
val result = dataSource.login(hostname, username, password)
if (result is Result.Success) {
setTokens(result.data)
setLoggedInUser(result.data)
}
return result
@ -46,7 +44,5 @@ class LoginRepository(val dataSource: ServerDataSource) {
private fun setLoggedInUser(loggedInUser: LoggedInUser) {
this.user = loggedInUser
// If user credentials will be cached in local storage, it is recommended it be encrypted
// @see https://developer.android.com/training/articles/keystore
}
}

View file

@ -1,33 +1,30 @@
package com.example.palto.ui.session
package com.example.palto.ui.attendanceList
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.example.palto.R
import com.example.palto.ui.session.placeholder.PlaceholderContent.PlaceholderItem
import com.example.palto.databinding.FragmentAttendanceBinding
import com.example.palto.ui.attendanceList.placeholder.PlaceholderContent.PlaceholderItem
import com.example.palto.databinding.FragmentAttendanceItemBinding
/**
* [RecyclerView.Adapter] that can display a [PlaceholderItem].
* TODO: Replace the implementation with code for your data type.
*/
class MyAttendanceRecyclerViewAdapter(
class AttendanceListAdapter(
private val values: List<PlaceholderItem>
) : RecyclerView.Adapter<MyAttendanceRecyclerViewAdapter.ViewHolder>() {
) : RecyclerView.Adapter<AttendanceListAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
FragmentAttendanceBinding.inflate(
FragmentAttendanceItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
@ -38,7 +35,7 @@ class MyAttendanceRecyclerViewAdapter(
override fun getItemCount(): Int = values.size
inner class ViewHolder(binding: FragmentAttendanceBinding) :
inner class ViewHolder(binding: FragmentAttendanceItemBinding) :
RecyclerView.ViewHolder(binding.root) {
val idView: TextView = binding.itemNumber
val contentView: TextView = binding.content
@ -47,5 +44,4 @@ class MyAttendanceRecyclerViewAdapter(
return super.toString() + " '" + contentView.text + "'"
}
}
}

View file

@ -0,0 +1,33 @@
package com.example.palto.ui.attendanceList
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.navigation.navGraphViewModels
import com.example.palto.R
import com.example.palto.ui.attendanceList.placeholder.PlaceholderContent
/**
* A fragment representing a list of attendances.
*/
class AttendanceListFragment : Fragment() {
private val attendanceListViewModel: AttendanceListViewModel by
navGraphViewModels(R.id.nav_graph)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_attendance_list, container, false)
if (view is RecyclerView) {
view.layoutManager = LinearLayoutManager(context)
view.adapter = AttendanceListAdapter(PlaceholderContent.ITEMS)
}
return view
}
}

View file

@ -0,0 +1,34 @@
package com.example.palto.ui.attendanceList
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.example.palto.data.network.ServerDataSource
import com.example.palto.data.repository.AttendanceRepository
import com.example.palto.data.repository.LoginRepository
class AttendanceListViewModel(
private val attendanceRepository: AttendanceRepository
) : ViewModel() {
/*
private val _loginForm = MutableLiveData<LoginFormState>()
val loginFormState: LiveData<LoginFormState> = _loginForm
private val _loginResult = MutableLiveData<LoginResult>()
val loginResult: LiveData<LoginResult> = _loginResult
*/
class AttendanceListViewModelFactory : ViewModelProvider.Factory {
//@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(AttendanceListViewModel::class.java)) {
return AttendanceListViewModel(
attendanceRepository = AttendanceRepository(
dataSource = ServerDataSource()
)
) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
}

View file

@ -0,0 +1,57 @@
package com.example.palto.ui.attendanceList.placeholder
import java.util.ArrayList
import java.util.HashMap
/**
* Helper class for providing sample content for user interfaces created by
* Android template wizards.
*
* TODO: Replace all uses of this class before publishing your app.
*/
object PlaceholderContent {
/**
* An array of sample (placeholder) items.
*/
val ITEMS: MutableList<PlaceholderItem> = ArrayList()
/**
* A map of sample (placeholder) items, by ID.
*/
val ITEM_MAP: MutableMap<String, PlaceholderItem> = HashMap()
private val COUNT = 25
init {
// Add some sample items.
for (i in 1..COUNT) {
addItem(createPlaceholderItem(i))
}
}
private fun addItem(item: PlaceholderItem) {
ITEMS.add(item)
ITEM_MAP.put(item.id, item)
}
private fun createPlaceholderItem(position: Int): PlaceholderItem {
return PlaceholderItem(position.toString(), "Item " + position, makeDetails(position))
}
private fun makeDetails(position: Int): String {
val builder = StringBuilder()
builder.append("Details about Item: ").append(position)
for (i in 0..position - 1) {
builder.append("\nMore details information here.")
}
return builder.toString()
}
/**
* A placeholder item representing a piece of content.
*/
data class PlaceholderItem(val id: String, val content: String, val details: String) {
override fun toString(): String = content
}
}

View file

@ -1,9 +1,13 @@
package com.example.palto.ui.login
/* Est-ce que cest util ?
* Updater la vue dans le fragment
*/
/**
* User details post authentication that is exposed to the UI
*/
data class LoggedInUserView(
val displayName: String
//... other data fields that may be accessible to the UI
)
)

View file

@ -1,7 +1,6 @@
package com.example.palto.ui.login
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.annotation.StringRes
import androidx.fragment.app.Fragment
import android.os.Bundle
@ -11,9 +10,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.EditText
import android.widget.ProgressBar
import android.widget.Toast
import androidx.navigation.fragment.findNavController
import androidx.navigation.navGraphViewModels
@ -24,7 +20,7 @@ import com.example.palto.R
class LoginFragment : Fragment() {
private val loginViewModel: LoginViewModel by
navGraphViewModels (R.id.nav_graph) { LoginViewModelFactory() }
navGraphViewModels(R.id.nav_graph) { LoginViewModelFactory() }
private var _binding: FragmentLoginBinding? = null

View file

@ -4,10 +4,12 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import android.util.Patterns
import androidx.lifecycle.ViewModelProvider
import com.example.palto.data.repository.LoginRepository
import com.example.palto.data.Result
import com.example.palto.R
import com.example.palto.data.network.ServerDataSource
class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel() {
@ -22,14 +24,17 @@ class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel()
username: String,
password: String) {
// can be launched in a separate asynchronous job
val result = loginRepository.login(username, password)
val result = loginRepository.login(hostname, username, password)
/*
if (result is Result.Success) {
_loginResult.value =
LoginResult(success = LoggedInUserView(displayName = result.data.displayName))
LoginResult(success = LoggedInUserView(
displayName = result.data.displayName))
} else {
_loginResult.value = LoginResult(error = R.string.login_failed)
}
*/
}
fun loginDataChanged(
@ -64,4 +69,17 @@ class LoginViewModel(private val loginRepository: LoginRepository) : ViewModel()
private fun isPasswordValid(password: String): Boolean {
return password.length > 5
}
}
}
class LoginViewModelFactory : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(LoginViewModel::class.java)) {
return LoginViewModel(
loginRepository = LoginRepository(
dataSource = ServerDataSource()
)
) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}

View file

@ -1,25 +0,0 @@
package com.example.palto.ui.login
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.example.palto.data.network.ServerDataSource
import com.example.palto.data.repository.LoginRepository
/**
* ViewModel provider factory to instantiate LoginViewModel.
* Required given LoginViewModel has a non-empty constructor
*/
class LoginViewModelFactory : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(LoginViewModel::class.java)) {
return LoginViewModel(
loginRepository = LoginRepository(
dataSource = ServerDataSource()
)
) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}

View file

@ -1,63 +0,0 @@
package com.example.palto.ui.session
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.palto.R
import com.example.palto.ui.session.placeholder.PlaceholderContent
/**
* A fragment representing a list of Items.
*/
class AttendanceListFragment : Fragment() {
private var columnCount = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
columnCount = it.getInt(ARG_COLUMN_COUNT)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_attendance_list, container, false)
// Set the adapter
if (view is RecyclerView) {
with(view) {
layoutManager = when {
columnCount <= 1 -> LinearLayoutManager(context)
else -> GridLayoutManager(context, columnCount)
}
adapter = MyAttendanceRecyclerViewAdapter(PlaceholderContent.ITEMS)
}
}
return view
}
companion object {
// TODO: Customize parameter argument names
const val ARG_COLUMN_COUNT = "column-count"
// TODO: Customize parameter initialization
@JvmStatic
fun newInstance(columnCount: Int) =
AttendanceListFragment().apply {
arguments = Bundle().apply {
putInt(ARG_COLUMN_COUNT, columnCount)
}
}
}
}

View file

@ -0,0 +1,44 @@
package com.example.palto.ui.sessionList
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import com.example.palto.ui.sessionList.placeholder.PlaceholderContent.PlaceholderItem
import com.example.palto.databinding.FragmentSessionItemBinding
/**
* [RecyclerView.Adapter] that can display a [PlaceholderItem].
*/
class SessionListAdapter(private val values: List<PlaceholderItem>) :
RecyclerView.Adapter<SessionListAdapter.ViewHolder>() {
class ViewHolder(binding: FragmentSessionItemBinding) :
RecyclerView.ViewHolder(binding.root) {
val idView: TextView = binding.itemNumber
val contentView: TextView = binding.content
override fun toString(): String {
return super.toString() + " '" + contentView.text + "'"
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = FragmentSessionItemBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = values[position]
holder.idView.text = item.id
holder.contentView.text = item.content
}
override fun getItemCount(): Int = values.size
}

View file

@ -0,0 +1,31 @@
package com.example.palto.ui.sessionList
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.palto.R
import com.example.palto.ui.sessionList.placeholder.PlaceholderContent
/**
* A fragment representing a list of Sessions.
*/
class SessionListFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_session_list, container, false)
if (view is RecyclerView) {
view.layoutManager = LinearLayoutManager(context)
view.adapter = SessionListAdapter(PlaceholderContent.ITEMS)
}
return view
}
}

View file

@ -0,0 +1,20 @@
package com.example.palto.ui.sessionList
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import android.util.Patterns
import com.example.palto.data.repository.LoginRepository
import com.example.palto.data.Result
import com.example.palto.R
class SessionListViewModel(private val loginRepository: LoginRepository) : ViewModel() {
/*
private val _loginForm = MutableLiveData<LoginFormState>()
val loginFormState: LiveData<LoginFormState> = _loginForm
private val _loginResult = MutableLiveData<LoginResult>()
val loginResult: LiveData<LoginResult> = _loginResult
*/
}

View file

@ -1,4 +1,4 @@
package com.example.palto.ui.session.placeholder
package com.example.palto.ui.sessionList.placeholder
import java.util.ArrayList
import java.util.HashMap

View file

@ -3,11 +3,11 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:name="com.example.palto.ui.session.AttendanceFragment"
android:name="com.example.palto.ui.attendanceList.AttendanceFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ui.session.AttendanceListFragment"
tools:listitem="@layout/fragment_attendance" />
tools:context=".ui.attendanceList.AttendanceListFragment"
tools:listitem="@layout/fragment_attendance_item" />

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/item_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem" />
<TextView
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/text_margin"
android:textAppearance="?attr/textAppearanceListItem" />
</LinearLayout>

View file

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/list"
android:name="com.example.palto.ui.session.SessionListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ui.sessionList.SessionListFragment"
tools:listitem="@layout/fragment_session_item" />

View file

@ -13,9 +13,14 @@
android:id="@+id/action_loginFragment_to_attendanceFragment"
app:destination="@id/attendanceFragment" />
</fragment>
<fragment
android:id="@+id/sessionListFragment"
android:name="com.example.palto.ui.sessionList.SessionListFragment"
android:label="fragment_session_list"
tools:layout="@layout/fragment_session_list" />
<fragment
android:id="@+id/attendanceFragment"
android:name="com.example.palto.ui.session.AttendanceListFragment"
android:name="com.example.palto.ui.attendanceList.AttendanceListFragment"
android:label="fragment_attendance_list"
tools:layout="@layout/fragment_attendance_list" />
</navigation>