Skip to content

Commit 8889e9a

Browse files
logout, images, date format done
Signed-off-by: Arnav Gupta <[email protected]>
1 parent 569dfce commit 8889e9a

File tree

11 files changed

+111
-21
lines changed

11 files changed

+111
-21
lines changed

app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ dependencies {
4848
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
4949
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
5050
implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'
51+
implementation "com.github.bumptech.glide:glide:4.11.0"
5152

5253
implementation project(":api")
5354

app/src/main/java/io/realworld/android/AuthViewModel.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ class AuthViewModel : ViewModel() {
1212
private val _user = MutableLiveData<User?>()
1313
val user: LiveData<User?> = _user
1414

15+
fun getCurrentUser(token: String) = viewModelScope.launch {
16+
UserRepo.getCurrentUser(token)?.let {
17+
_user.postValue(it)
18+
}
19+
}
20+
1521
fun login(email: String, password: String) = viewModelScope.launch {
1622
UserRepo.login(email, password)?.let {
1723
_user.postValue(it)
@@ -24,6 +30,10 @@ class AuthViewModel : ViewModel() {
2430
}
2531
}
2632

33+
fun logout() {
34+
_user.postValue(null)
35+
}
36+
2737
fun update(
2838
bio: String?,
2939
username: String?,

app/src/main/java/io/realworld/android/MainActivity.kt

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package io.realworld.android
22

3+
import android.content.Context
4+
import android.content.SharedPreferences
35
import android.os.Bundle
46
import android.view.Menu
5-
import android.widget.Toast
7+
import android.view.MenuItem
68
import androidx.appcompat.app.AppCompatActivity
9+
import androidx.core.content.edit
710
import androidx.drawerlayout.widget.DrawerLayout
811
import androidx.lifecycle.ViewModelProvider
912
import androidx.navigation.findNavController
@@ -17,16 +20,23 @@ import io.realworld.api.models.entities.User
1720

1821
class MainActivity : AppCompatActivity() {
1922

23+
companion object {
24+
const val PREFS_FILE_AUTH = "prefs_auth"
25+
const val PREFS_KEY_TOKEN = "token"
26+
}
27+
2028
private lateinit var appBarConfiguration: AppBarConfiguration
2129
private lateinit var binding: ActivityMainBinding
2230
private lateinit var authViewModel: AuthViewModel
31+
private lateinit var sharedPreferences: SharedPreferences
2332

2433
override fun onCreate(savedInstanceState: Bundle?) {
2534
super.onCreate(savedInstanceState)
2635

36+
sharedPreferences = getSharedPreferences(PREFS_FILE_AUTH, Context.MODE_PRIVATE)
2737
authViewModel = ViewModelProvider(this).get(AuthViewModel::class.java)
28-
2938
binding = ActivityMainBinding.inflate(layoutInflater)
39+
3040
setContentView(binding.root)
3141

3242
setSupportActionBar(binding.appBarMain.toolbar)
@@ -46,10 +56,25 @@ class MainActivity : AppCompatActivity() {
4656
setupActionBarWithNavController(navController, appBarConfiguration)
4757
navView.setupWithNavController(navController)
4858

59+
sharedPreferences.getString(PREFS_KEY_TOKEN, null)?.let { t ->
60+
authViewModel.getCurrentUser(t)
61+
}
62+
4963
authViewModel.user.observe({ lifecycle }) {
5064
updateMenu(it)
65+
it?.token?.let { t ->
66+
sharedPreferences.edit {
67+
putString(PREFS_KEY_TOKEN, t)
68+
}
69+
} ?: run {
70+
sharedPreferences.edit {
71+
remove(PREFS_KEY_TOKEN)
72+
}
73+
}
5174
navController.navigateUp()
5275
}
76+
77+
5378
}
5479

5580
private fun updateMenu(user: User?) {
@@ -59,12 +84,23 @@ class MainActivity : AppCompatActivity() {
5984
binding.navView.inflateMenu(R.menu.menu_main_user)
6085
}
6186
else -> {
62-
87+
binding.navView.menu.clear()
88+
binding.navView.inflateMenu(R.menu.menu_main_guest)
6389
}
6490
}
6591

6692
}
6793

94+
override fun onOptionsItemSelected(item: MenuItem): Boolean {
95+
when (item.itemId) {
96+
R.id.action_logout -> {
97+
authViewModel.logout()
98+
return true
99+
}
100+
}
101+
return super.onOptionsItemSelected(item)
102+
}
103+
68104
override fun onCreateOptionsMenu(menu: Menu): Boolean {
69105
// Inflate the menu; this adds items to the action bar if it is present.
70106
menuInflater.inflate(R.menu.main, menu)

app/src/main/java/io/realworld/android/data/UserRepo.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ object UserRepo {
3535

3636
}
3737

38+
suspend fun getCurrentUser(token: String): User? {
39+
ConduitClient.authToken = token
40+
return authAPI.getCurrentUser().body()?.user
41+
}
42+
3843
suspend fun updateUser(
3944
bio: String?,
4045
username: String?,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.realworld.android.extensions
2+
3+
import android.widget.ImageView
4+
import com.bumptech.glide.Glide
5+
6+
fun ImageView.loadImage(uri: String, circleCrop: Boolean = false) {
7+
if (circleCrop) {
8+
Glide.with(this).load(uri).circleCrop().into(this)
9+
} else {
10+
Glide.with(this).load(uri).into(this)
11+
}
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.realworld.android.extensions
2+
3+
import android.annotation.SuppressLint
4+
import android.icu.text.SimpleDateFormat
5+
import android.widget.TextView
6+
import java.util.*
7+
8+
@SuppressLint("ConstantLocale")
9+
val isoDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.getDefault())
10+
11+
@SuppressLint("ConstantLocale")
12+
val appDateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault())
13+
14+
var TextView.timeStamp: String
15+
set(value) {
16+
val date = isoDateFormat.parse(value)
17+
text = appDateFormat.format(date)
18+
}
19+
get() {
20+
val date = appDateFormat.parse(text.toString())
21+
return isoDateFormat.format(date)
22+
}

app/src/main/java/io/realworld/android/ui/article/ArticleFragment.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import androidx.fragment.app.Fragment
88
import androidx.lifecycle.ViewModelProvider
99
import io.realworld.android.R
1010
import io.realworld.android.databinding.FragmentArticleBinding
11+
import io.realworld.android.extensions.loadImage
12+
import io.realworld.android.extensions.timeStamp
1113

1214
class ArticleFragment : Fragment() {
1315

@@ -40,7 +42,8 @@ class ArticleFragment : Fragment() {
4042
titleTextView.text = it.title
4143
bodyTextView.text = it.body
4244
authorTextView.text = it.author.username
43-
dateTextView.text = it.createdAt // TODO: format
45+
dateTextView.timeStamp = it.createdAt
46+
avatarImageView.loadImage(it.author.image, true)
4447
}
4548
}
4649

app/src/main/java/io/realworld/android/ui/feed/ArticleFeedAdapter.kt

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package io.realworld.android.ui.feed
22

3-
import android.graphics.Color
4-
import android.graphics.drawable.ColorDrawable
53
import android.view.LayoutInflater
64
import android.view.View
75
import android.view.ViewGroup
@@ -10,19 +8,22 @@ import androidx.recyclerview.widget.ListAdapter
108
import androidx.recyclerview.widget.RecyclerView
119
import io.realworld.android.R
1210
import io.realworld.android.databinding.ListItemArticleBinding
11+
import io.realworld.android.extensions.loadImage
12+
import io.realworld.android.extensions.timeStamp
1313
import io.realworld.api.models.entities.Article
1414

15-
class ArticleFeedAdapter(val onArticleClicked: (slug: String) -> Unit) : ListAdapter<Article, ArticleFeedAdapter.ArticleViewHolder>(
16-
object : DiffUtil.ItemCallback<Article>() {
17-
override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean {
18-
return oldItem == newItem
19-
}
15+
class ArticleFeedAdapter(val onArticleClicked: (slug: String) -> Unit) :
16+
ListAdapter<Article, ArticleFeedAdapter.ArticleViewHolder>(
17+
object : DiffUtil.ItemCallback<Article>() {
18+
override fun areItemsTheSame(oldItem: Article, newItem: Article): Boolean {
19+
return oldItem == newItem
20+
}
2021

21-
override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean {
22-
return oldItem.toString() == newItem.toString()
22+
override fun areContentsTheSame(oldItem: Article, newItem: Article): Boolean {
23+
return oldItem.toString() == newItem.toString()
24+
}
2325
}
24-
}
25-
) {
26+
) {
2627
inner class ArticleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
2728

2829
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleViewHolder {
@@ -42,8 +43,8 @@ class ArticleFeedAdapter(val onArticleClicked: (slug: String) -> Unit) : ListAda
4243
authorTextView.text = article.author.username
4344
titleTextView.text = article.title
4445
bodySnippetTextView.text = article.body
45-
dateTextView.text = "December 15, 2020" //TODO: format actual date
46-
avatarImageView.background = ColorDrawable(Color.GRAY) //TODO: show real image
46+
dateTextView.timeStamp = article.createdAt
47+
avatarImageView.loadImage(article.author.image, true)
4748

4849
root.setOnClickListener { onArticleClicked(article.slug) }
4950

app/src/main/res/layout/fragment_article.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
android:id="@+id/avatarImageView"
2626
android:layout_width="32dp"
2727
android:layout_height="32dp"
28-
android:background="@color/conduit_grey" />
28+
tools:background="@color/conduit_grey" />
2929

3030
<LinearLayout
3131
android:layout_width="wrap_content"

app/src/main/res/menu/main.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<menu xmlns:android="http://schemas.android.com/apk/res/android"
33
xmlns:app="http://schemas.android.com/apk/res-auto">
44
<item
5-
android:id="@+id/action_settings"
5+
android:id="@+id/action_logout"
66
android:orderInCategory="100"
7-
android:title="@string/action_settings"
7+
android:title="@string/action_logout"
88
app:showAsAction="never" />
99
</menu>

0 commit comments

Comments
 (0)