Skip to content

Commit e236bff

Browse files
addition of illlustration, improved state management and onboarding modified
1 parent 62f83fb commit e236bff

31 files changed

+539
-59
lines changed

app/src/main/java/com/github/code/gambit/ui/BaseAdapter.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ abstract class BaseAdapter<T, B : ViewBinding, LS : OnItemClickListener<T>>(priv
115115
/**
116116
* Sets the view which is displayed when list is empty
117117
*/
118-
fun bindEmptyListView(view: View) {
118+
fun bindEmptyView(view: View) {
119119
emptyIndicatorView = view
120120
}
121121

@@ -140,6 +140,15 @@ abstract class BaseAdapter<T, B : ViewBinding, LS : OnItemClickListener<T>>(priv
140140
}
141141
}
142142

143+
fun refresh(clearCounter: Boolean = false) {
144+
refreshEmptyIndicatorState()
145+
if (clearCounter) {
146+
counterView?.text = ""
147+
} else {
148+
updateCounterText()
149+
}
150+
}
151+
143152
/**
144153
* Returns the item <T> from [dataList] at specific position
145154
* @param position : position of item in [dataList]

app/src/main/java/com/github/code/gambit/ui/activity/main/MainActivity.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,9 @@ class MainActivity : AppCompatActivity(), BottomNavController {
140140
override fun onItemLongClick(item: FileUploadStatus) {}
141141
}
142142
val layoutManager = LinearLayoutManager(this)
143-
binding.secondaryContainer.layoutManager = layoutManager
144-
binding.secondaryContainer.setHasFixedSize(false)
145-
binding.secondaryContainer.adapter = adapter
143+
binding.metaDataListItem.layoutManager = layoutManager
144+
binding.metaDataListItem.setHasFixedSize(false)
145+
binding.metaDataListItem.adapter = adapter
146146
}
147147

148148
private fun setupClickListeners() {
@@ -239,7 +239,11 @@ class MainActivity : AppCompatActivity(), BottomNavController {
239239
}
240240

241241
fun getAddFab(): View {
242-
return binding.addFileButton
242+
return binding.bottomNavContainerRoot
243+
}
244+
245+
fun getDragView(): View {
246+
return binding.constraintLayout
243247
}
244248

245249
override fun animateBottomNav(offset: Float) {

app/src/main/java/com/github/code/gambit/ui/fragment/home/main/HomeFragment.kt

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,9 @@ import com.github.code.gambit.utility.extention.show
3535
import com.github.code.gambit.utility.extention.showDefaultMaterialAlert
3636
import com.github.code.gambit.utility.extention.snackbar
3737
import com.github.code.gambit.utility.sharedpreference.LastEvaluatedKeyManager
38+
import com.github.code.gambit.utility.sharedpreference.UserManager
3839
import com.google.android.material.bottomsheet.BottomSheetBehavior
3940
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
40-
import com.takusemba.spotlight.OnSpotlightListener
41-
import com.takusemba.spotlight.OnTargetListener
4241
import com.takusemba.spotlight.Spotlight
4342
import com.takusemba.spotlight.Target
4443
import com.takusemba.spotlight.shape.Circle
@@ -74,6 +73,9 @@ class HomeFragment : Fragment(R.layout.fragment_home), FileUrlClickCallback, Bot
7473
@Inject
7574
lateinit var lekManager: LastEvaluatedKeyManager
7675

76+
@Inject
77+
lateinit var userManager: UserManager
78+
7779
private lateinit var fileSearchComponent: FileSearchComponent
7880
private lateinit var filterComponent: FilterComponent
7981

@@ -125,7 +127,6 @@ class HomeFragment : Fragment(R.layout.fragment_home), FileUrlClickCallback, Bot
125127
setUpFileRecyclerView()
126128
registerEventCallbacks()
127129
viewModel.setEvent(HomeEvent.GetFiles)
128-
// Handler().postDelayed({ spotlight() }, 6000)
129130
}
130131

131132
private fun registerEventCallbacks() {
@@ -206,7 +207,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), FileUrlClickCallback, Bot
206207
}
207208

208209
private fun setUpFileRecyclerView() {
209-
adapter.bindEmptyListView(binding.noFileIllustrationContainer)
210+
adapter.bindEmptyView(binding.noFileIllustrationContainer)
210211
val layoutManager = LinearLayoutManager(requireContext())
211212
binding.fileList.layoutManager = layoutManager
212213
binding.fileList.setHasFixedSize(false)
@@ -303,6 +304,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), FileUrlClickCallback, Bot
303304
binding.topContainer.show()
304305
binding.swipeRefresh.show()
305306
binding.fileList.show()
307+
spotlight()
306308
}
307309

308310
private fun showShimmer() {
@@ -313,70 +315,64 @@ class HomeFragment : Fragment(R.layout.fragment_home), FileUrlClickCallback, Bot
313315
}
314316

315317
private fun spotlight() {
318+
if (userManager.isHomeOnBoarded()) {
319+
return
320+
}
316321
val targets = ArrayList<Target>()
317322

318323
val firstRoot = FrameLayout(requireContext())
319-
val first = layoutInflater.inflate(R.layout.home_first_spot, firstRoot)
320-
val firstTarget = Target.Builder()
321-
.setAnchor(requireMainActivity().getAddFab())
322-
.setShape(Circle(120f))
323-
.setOverlay(first)
324-
.setOnTargetListener(object : OnTargetListener {
325-
override fun onEnded() {}
326-
override fun onStarted() {}
327-
})
328-
.build()
324+
val first = layoutInflater.inflate(R.layout.home_add_file_spot, firstRoot)
325+
val firstTarget = getTarget(requireMainActivity().getAddFab(), first, 250)
329326

330327
val secondRoot = FrameLayout(requireContext())
331-
val second = layoutInflater.inflate(R.layout.home_second_spot, secondRoot)
332-
val secondTarget = Target.Builder()
333-
.setAnchor(binding.searchButton)
334-
.setShape(Circle(50f))
335-
.setOverlay(second)
336-
.setOnTargetListener(object : OnTargetListener {
337-
override fun onEnded() {}
338-
override fun onStarted() {}
339-
}).build()
340-
341-
val thirdTarget = Target.Builder()
342-
.setAnchor(binding.filterButton)
343-
.setShape(Circle(50f))
344-
.setOverlay(second)
345-
.setOnTargetListener(object : OnTargetListener {
346-
override fun onEnded() {}
347-
override fun onStarted() {}
348-
}).build()
328+
val second = layoutInflater.inflate(R.layout.home_drag_spot, secondRoot)
329+
val secondTarget = getTarget(requireMainActivity().getDragView(), second, 100)
330+
331+
val thirdRoot = FrameLayout(requireContext())
332+
val third = layoutInflater.inflate(R.layout.home_search_filter_spot, thirdRoot)
333+
val thirdTarget = getTarget(binding.searchButton, third)
334+
335+
val fourthTarget = getTarget(binding.filterButton, third)
349336

350337
targets.add(firstTarget)
351338
targets.add(secondTarget)
352339
targets.add(thirdTarget)
340+
targets.add(fourthTarget)
353341

354342
val spotlight = Spotlight.Builder(requireActivity())
355343
.setTargets(targets)
356344
.setBackgroundColorRes(R.color.spotlightBackground)
357345
.setDuration(1000L)
358346
.setAnimation(DecelerateInterpolator(2f))
359-
.setOnSpotlightListener(object : OnSpotlightListener {
360-
override fun onStarted() {}
361-
override fun onEnded() {}
362-
}).build()
347+
.build()
363348

364349
spotlight.start()
365350

366351
val nextTarget = View.OnClickListener { spotlight.next() }
367352

368-
// val closeSpotlight = View.OnClickListener { spotlight.finish() }
353+
val closeSpotlight = View.OnClickListener {
354+
userManager.updateHomeOnBoardingState()
355+
spotlight.finish()
356+
}
369357

370358
first.findViewById<View>(R.id.next_button).setOnClickListener(nextTarget)
371-
second.findViewById<View>(R.id.next_button).setOnClickListener {
359+
second.findViewById<View>(R.id.next_button).setOnClickListener(nextTarget)
360+
third.findViewById<View>(R.id.next_button).setOnClickListener {
372361
spotlight.next()
373-
second.findViewById<TextView>(R.id.title_text).text = getString(R.string.use_filters)
374-
second.findViewById<TextView>(R.id.info_text).text =
362+
third.findViewById<TextView>(R.id.title_text).text = getString(R.string.use_filters)
363+
third.findViewById<TextView>(R.id.info_text).text =
375364
getString(R.string.or_you_can_filter_files_based_on_dates_they_were_uploaded)
376-
second.findViewById<View>(R.id.arrow).animate().rotation(105f).setDuration(500).start()
365+
third.findViewById<View>(R.id.arrow).animate().rotation(105f).setDuration(500).start()
366+
third.findViewById<View>(R.id.next_button).setOnClickListener(closeSpotlight)
377367
}
378368
}
379369

370+
private fun getTarget(anchorView: View, overlay: View, radius: Int = 50): Target {
371+
return Target.Builder().setAnchor(anchorView).setShape(Circle(radius.toFloat()))
372+
.setOverlay(overlay)
373+
.build()
374+
}
375+
380376
private fun showFilter() {
381377
animateBottomNav(0f)
382378
binding.overlay.show()
@@ -399,6 +395,7 @@ class HomeFragment : Fragment(R.layout.fragment_home), FileUrlClickCallback, Bot
399395

400396
fun closeSearch() {
401397
hideKeyboard()
398+
adapter.bindEmptyView(binding.noFileIllustrationContainer)
402399
adapter.restore()
403400
searchBinding.root.hide()
404401
showBottomNav()

app/src/main/java/com/github/code/gambit/ui/fragment/home/searchcomponent/FileSearchComponentImpl.kt

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@ import android.content.Context
44
import android.text.Editable
55
import android.text.TextWatcher
66
import android.view.View
7+
import androidx.core.content.ContextCompat
78
import androidx.lifecycle.MutableLiveData
89
import androidx.recyclerview.widget.LinearLayoutManager
10+
import com.github.code.gambit.R
911
import com.github.code.gambit.data.model.File
1012
import com.github.code.gambit.data.model.Url
1113
import com.github.code.gambit.databinding.SearchLayoutBinding
@@ -20,14 +22,17 @@ class FileSearchComponentImpl(
2022
) : FileSearchComponent, FileUrlClickCallback {
2123

2224
val fileSearchRequest = MutableLiveData<String>()
25+
private var context: Context? = null
2326

24-
fun registerComponents(context: Context, closeFunc: () -> Unit) {
27+
fun registerComponents(ctx: Context, closeFunc: () -> Unit) {
28+
this.context = ctx
2529
adapter.bindCounterView(binding.counter)
2630
binding.fileList.layoutManager = LinearLayoutManager(context)
2731
binding.fileList.setHasFixedSize(false)
2832
binding.fileList.adapter = adapter
2933
adapter.listener = this
3034
binding.homeButton.setOnClickListener {
35+
setIllustrationState(true)
3136
closeFunc()
3237
}
3338
binding.searchInput.editText?.addTextChangedListener(object : TextWatcher {
@@ -37,15 +42,21 @@ class FileSearchComponentImpl(
3742
val text = p0.toString()
3843
if (text.length >= 3) {
3944
newSearch(text)
45+
} else if (text.isEmpty()) {
46+
setIllustrationState(true)
47+
adapter.addAll(listOf(), true)
4048
}
4149
}
4250

4351
override fun afterTextChanged(p0: Editable?) {}
4452
})
53+
show()
4554
}
4655

4756
override fun show() {
4857
binding.searchInput.editText?.setText("")
58+
adapter.bindEmptyView(binding.illustration)
59+
adapter.refresh(true)
4960
}
5061

5162
private fun newSearch(searchString: String) {
@@ -59,6 +70,28 @@ class FileSearchComponentImpl(
5970
override fun setFileLoaded(files: List<File>) {
6071
(binding.progressBar as View).hide()
6172
adapter.addAll(files as ArrayList<File>, true)
73+
if (files.isEmpty()) {
74+
setIllustrationState()
75+
}
76+
}
77+
78+
/**
79+
* @param isFirstState `true` if want to set the state to initial/first state else to second
80+
*/
81+
private fun setIllustrationState(isFirstState: Boolean = false) {
82+
context?.let {
83+
if (isFirstState) {
84+
binding.illustration.setImageDrawable(
85+
ContextCompat.getDrawable(it, R.drawable.illus_void)
86+
)
87+
binding.infoMessage.text = it.getString(R.string.file_search_info)
88+
} else {
89+
binding.illustration.setImageDrawable(
90+
ContextCompat.getDrawable(it, R.drawable.illus_error)
91+
)
92+
binding.infoMessage.text = it.getString(R.string.empty_file_search_result)
93+
}
94+
}
6295
}
6396

6497
override fun getRequests(): MutableLiveData<String> {

app/src/main/java/com/github/code/gambit/utility/sharedpreference/PreferenceManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ abstract class PreferenceManager(var context: Context) {
4747
enum class Key(val value: String) {
4848
LAUNCHSTATE("IS-FIRST-LAUNCH"),
4949
AUTHSTATE("IS-AUTHENTICATED"),
50+
HOMEONBOARDINGSTATE("IS-HOME-ONBOARDED"),
5051
USER("USER"),
5152
TOKEN("ID-TOKEN"),
5253
FILE_LEK("FILE-LAST-EVALUATED-KEY"),

app/src/main/java/com/github/code/gambit/utility/sharedpreference/UserManager.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ constructor(@ApplicationContext context: Context) : PreferenceManager(context) {
3838

3939
fun isFirstLaunch() = get(Key.LAUNCHSTATE, true)
4040

41+
fun isHomeOnBoarded() = get(Key.HOMEONBOARDINGSTATE, false)
42+
43+
fun updateHomeOnBoardingState(isOnBoarded: Boolean = true) =
44+
put(Key.HOMEONBOARDINGSTATE, isOnBoarded)
45+
4146
private fun updateLaunchState() = put(Key.LAUNCHSTATE, false)
4247

4348
private fun updateIdToken(token: String?) = put(Key.TOKEN, token)

0 commit comments

Comments
 (0)