Initial commit

This commit is contained in:
2024-05-02 14:49:19 +05:30
commit 56d7b7a3ba
154 changed files with 13363 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
package com.woka
import android.app.Application
import com.woka.userPreference.UserPreference
class WokaApp: Application() {
companion object{
var userPrefs: UserPreference? = null
}
override fun onCreate() {
super.onCreate()
userPrefs = UserPreference(applicationContext)
}
}

View File

@@ -0,0 +1,33 @@
package com.woka.onboard
import android.content.Context
import android.widget.LinearLayout
import android.widget.TextView
import androidx.cardview.widget.CardView
import com.woka.R
class InterestTopicView(context: Context, topicName: String): LinearLayout(context) {
var isTopicSelected = false
private set
init {
inflate(context, R.layout.layout_interest_topic, this)
findViewById<TextView>(R.id.interest_topic_txt).text = topicName
findViewById<CardView>(R.id.interest_card).setOnClickListener {
val card = it as CardView
if (!isTopicSelected){
card.setCardBackgroundColor(context.resources.getColor(R.color.white))
card.elevation = 5f
}else{
card.setCardBackgroundColor(context.resources.getColor(R.color.white_60))
card.elevation = 0f
}
isTopicSelected = !isTopicSelected
}
}
constructor(context: Context): this(context, "None")
}

View File

@@ -0,0 +1,46 @@
package com.woka.onboard
import android.media.MediaPlayer
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import com.woka.R
import com.woka.utils.WokaBaseActivity
class OnboardActivity : WokaBaseActivity() {
private var player: MediaPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_onboard)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
player = MediaPlayer.create(this, R.raw.audiotwo)
player?.isLooping = true
}
override fun onStart() {
super.onStart()
player?.start()
}
override fun onStop() {
super.onStop()
player?.pause()
}
override fun onDestroy() {
super.onDestroy()
player?.stop()
player?.release()
player = null
}
}

View File

@@ -0,0 +1,43 @@
package com.woka.onboard
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.woka.R
import com.woka.databinding.OnboardSlideBinding
class OnboardingAdapter : RecyclerView.Adapter<OnboardingAdapter.ViewHolder>() {
class ViewHolder(val binding: OnboardSlideBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ViewHolder(
OnboardSlideBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
with(holder) {
val context = binding.root.context
binding.apply {
when (position){
0 -> {
title.text = context.getString(R.string.slide_1_title)
subtitle.text = context.getString(R.string.slide_1_subtitle)
image.setImageResource(R.drawable.slide1)
}
1 -> {
title.text = context.getString(R.string.slide_2_title)
// subtitle.text = context.getString(R.string.slide_2_subtitle)
image.setImageResource(R.drawable.slide2)
}
2 ->{
title.text = context.getString(R.string.slide_3_title)
// subtitle.text = context.getString(R.string.slide_3_subtitle)
image.setImageResource(R.drawable.slide3)
}
}
}
}
}
override fun getItemCount() = 3
}

View File

@@ -0,0 +1,24 @@
package com.woka.onboard
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.woka.R
import com.woka.utils.WokaBaseActivity
class WelcomeActivity : WokaBaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
enableEdgeToEdge()
setContentView(R.layout.activity_welcome)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
}
}

View File

@@ -0,0 +1,49 @@
package com.woka.onboard.fragments
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.woka.R
import com.woka.databinding.FragmentAgeSelectBinding
import com.woka.onboard.fragments.GetEmailFragment.Companion.IS_UNDER_16
class AgeSelectionFragment : Fragment() {
private lateinit var binding: FragmentAgeSelectBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentAgeSelectBinding.inflate(inflater, container, false)
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
activity?.window?.statusBarColor = Color.parseColor("#6ed5fe")
clickEvents()
return binding.root
}
private fun clickEvents() {
binding.under26.setOnClickListener {
val args = Bundle()
args.putBoolean(IS_UNDER_16, true)
findNavController().navigate(R.id.action_age_select_fragment_to_getEmailFragment, args)
}
binding.above16.setOnClickListener {
val args = Bundle()
args.putBoolean(IS_UNDER_16, false)
findNavController().navigate(R.id.action_age_select_fragment_to_getEmailFragment, args)
}
binding.backBtn.setOnClickListener{
activity?.onBackPressedDispatcher?.onBackPressed()
}
}
}

View File

@@ -0,0 +1,96 @@
package com.woka.onboard.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.widget.addTextChangedListener
import androidx.navigation.fragment.findNavController
import com.woka.R
import com.woka.databinding.FragmentGetCodeBinding
import com.woka.onboard.fragments.GetEmailFragment.Companion.IS_UNDER_16
import com.woka.utils.closeKeyboard
class GetCodeFragment : Fragment() {
private lateinit var binding: FragmentGetCodeBinding
private var isUnder16 = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
isUnder16 = it.getBoolean(IS_UNDER_16, false)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentGetCodeBinding.inflate(inflater, container, false)
initViews()
clickEvents()
return binding.root
}
private fun initViews() {
binding.apply {
et1.addTextChangedListener {
if (it?.isEmpty() == false){
et2.requestFocus()
}
}
et2.addTextChangedListener {
if (it?.isEmpty() == false){
et3.requestFocus()
}else{
et1.requestFocus()
}
}
et3.addTextChangedListener {
if (it?.isEmpty() == false){
et4.requestFocus()
}else{
et2.requestFocus()
}
}
et4.addTextChangedListener {
if (it?.isEmpty() == false){
// close keyboard
activity?.closeKeyboard()
}else{
et3.requestFocus()
}
}
if (isUnder16){
title.text = getString(R.string.please_get_otp_under_16)
infoText.text = getString(R.string.request_them_for_verification_)
}
binding.next.setOnClickListener {
val args = Bundle().apply {
putBoolean(IS_UNDER_16, isUnder16)
}
findNavController().navigate(R.id.action_getCodeFragment_to_signUpFragment, args)
}
}
}
private fun clickEvents() {
binding.apply {
backBtn.setOnClickListener {
activity?.onBackPressedDispatcher?.onBackPressed()
}
}
}
}

View File

@@ -0,0 +1,76 @@
package com.woka.onboard.fragments
import android.os.Bundle
import android.util.Patterns
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.Toast
import androidx.navigation.fragment.findNavController
import com.woka.R
import com.woka.databinding.FragmentGetEmailBinding
class GetEmailFragment : Fragment() {
companion object{
const val IS_UNDER_16 = "is_under_16"
}
private lateinit var binding: FragmentGetEmailBinding
private var isUnder16: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
isUnder16 = it.getBoolean(IS_UNDER_16, false)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentGetEmailBinding.inflate(inflater, container, false)
initViews()
clickEvents()
return binding.root
}
private fun initViews() {
binding.apply {
if (isUnder16){
title.text = getString(R.string.let_s_be_safe)
can.text = getString(R.string.can_we_have_your_parent_s_email)
email.hint = getString(R.string.enter_your_parent_s_email)
verificationTxt.visibility = VISIBLE
}
}
}
private fun clickEvents() {
binding.next.setOnClickListener {
binding.email.error = null
if (!Patterns.EMAIL_ADDRESS.matcher(binding.email.text.toString()).matches()){
binding.email.error = "Invalid email"
return@setOnClickListener
}
val args = Bundle().apply {
putBoolean(IS_UNDER_16, isUnder16)
}
findNavController().navigate(R.id.action_getEmailFragment_to_getCodeFragment, args)
}
binding.backBtn.setOnClickListener {
activity?.onBackPressedDispatcher?.onBackPressed()
}
}
}

View File

@@ -0,0 +1,112 @@
package com.woka.onboard.fragments
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
import androidx.core.view.allViews
import androidx.fragment.app.Fragment
import com.woka.R
import com.woka.databinding.FragmentGetMoreInfoBinding
import com.woka.onboard.InterestTopicView
import com.woka.onboard.fragments.GetEmailFragment.Companion.IS_UNDER_16
import com.woka.onboard.models.Interest
import com.woka.utils.Gender
class GetMoreInfoFragment : Fragment() {
companion object{
const val USER_NAME_ARG = "arg_user_name"
}
private lateinit var binding: FragmentGetMoreInfoBinding
private var isUnder16 = false
private var userName: String? = null
private var selectedGender: Gender = Gender.NONE
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
isUnder16 = it.getBoolean(IS_UNDER_16)
userName = it.getString(USER_NAME_ARG)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentGetMoreInfoBinding.inflate(inflater, container, false)
initViews()
clickEvents()
return binding.root
}
private fun clickEvents() {
binding.apply {
genderM.setOnClickListener{selectGender(Gender.MALE)}
genderF.setOnClickListener{selectGender(Gender.FEMALE)}
backBtn.setOnClickListener { activity?.onBackPressedDispatcher?.onBackPressed() }
}
}
private fun initViews() {
selectGender(selectedGender)
binding.apply {
if (isUnder16){
interestView.visibility = VISIBLE
// static
interestsFlex.apply {
addView(InterestTopicView(context, "English"))
addView(InterestTopicView(context, "Maths"))
addView(InterestTopicView(context, "Science"))
addView(InterestTopicView(context, "Entertainment"))
addView(InterestTopicView(context, "Education"))
}
}
name.text = userName
}
}
private fun selectGender(gender: Gender){
if (selectedGender == gender) return
binding.apply {
when(gender){
Gender.MALE -> {
genderM.setCardBackgroundColor(Color.WHITE)
genderM.cardElevation = 5f
genderF.setCardBackgroundColor(resources.getColor(R.color.white_50))
genderF.cardElevation = 0f
}
Gender.FEMALE -> {
genderF.setCardBackgroundColor(Color.WHITE)
genderF.cardElevation = 5f
genderM.setCardBackgroundColor(resources.getColor(R.color.white_50))
genderM.cardElevation = 0f
}
Gender.NONE -> {
genderM.setCardBackgroundColor(resources.getColor(R.color.white_50))
genderM.cardElevation = 0f
genderF.setCardBackgroundColor(resources.getColor(R.color.white_50))
genderF.cardElevation = 0f
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
package com.woka.onboard.fragments
import android.content.Intent
import android.os.Bundle
import android.transition.TransitionInflater
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.app.ActivityOptionsCompat
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import com.woka.R
import com.woka.databinding.FragmentLanguageBinding
import com.woka.onboard.OnboardActivity
import com.woka.utils.changeLocale
class LanguageFragment : Fragment() {
private lateinit var binding: FragmentLanguageBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentLanguageBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
clickEvents()
}
private fun clickEvents() {
binding.english.setOnClickListener {
requireActivity().changeLocale("en")
gotoOnboardActivity()
}
binding.hindi.setOnClickListener {
requireActivity().changeLocale("hi")
gotoOnboardActivity()
}
}
private fun gotoOnboardActivity() {
startActivity(Intent(requireActivity(), OnboardActivity::class.java),
ActivityOptionsCompat.makeSceneTransitionAnimation(requireActivity(),
binding.logo, "logo").toBundle())
}
}

View File

@@ -0,0 +1,60 @@
package com.woka.onboard.fragments
import android.graphics.Color
import android.os.Bundle
import android.transition.TransitionInflater
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.tabs.TabLayoutMediator
import com.woka.R
import com.woka.databinding.FragmentOnboardBinding
import com.woka.onboard.OnboardingAdapter
class OnboardFragment : Fragment() {
private lateinit var binding: FragmentOnboardBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(android.R.transition.move)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentOnboardBinding.inflate(inflater, container, false)
activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
activity?.window?.statusBarColor = Color.parseColor("#55cffe")
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
initViews()
clickEvents()
}
private fun initViews() {
binding.apply {
viewPager.adapter = OnboardingAdapter()
TabLayoutMediator(tabLayout, viewPager){tab, position -> }.attach()
}
}
private fun clickEvents(){
binding.backBtn.setOnClickListener{
activity?.onBackPressedDispatcher?.onBackPressed()
}
binding.createAccount.setOnClickListener {
findNavController().navigate(R.id.action_onboardFragment_to_age_select_fragment)
}
}
}

View File

@@ -0,0 +1,23 @@
package com.woka.onboard.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.woka.R
import com.woka.databinding.FragmentSelectAvatarBinding
class SelectAvatarFragment : Fragment() {
private lateinit var binding: FragmentSelectAvatarBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSelectAvatarBinding.inflate(inflater, container, false)
return binding.root
}
}

View File

@@ -0,0 +1,33 @@
package com.woka.onboard.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.woka.R
import com.woka.databinding.FragmentSignInBinding
class SignInFragment : Fragment() {
private lateinit var binding: FragmentSignInBinding
private var isUnder16 = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSignInBinding.inflate(inflater, container, false)
clickEvents()
return binding.root
}
private fun clickEvents() {
binding.apply {
}
}
}

View File

@@ -0,0 +1,65 @@
package com.woka.onboard.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import com.woka.R
import com.woka.databinding.FragmentSignUpBinding
import com.woka.onboard.fragments.GetEmailFragment.Companion.IS_UNDER_16
import com.woka.onboard.fragments.GetMoreInfoFragment.Companion.USER_NAME_ARG
class SignUpFragment : Fragment() {
private lateinit var binding: FragmentSignUpBinding
private var isUnder16 = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
isUnder16 = it.getBoolean(IS_UNDER_16, false)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSignUpBinding.inflate(inflater, container, false)
initViews()
clickEvents()
return binding.root
}
private fun initViews() {
binding.apply {
if (isUnder16){
doNotShare.visibility = VISIBLE
}
}
}
private fun clickEvents() {
binding.apply {
backBtn.setOnClickListener {
activity?.onBackPressedDispatcher?.onBackPressed()
}
next.setOnClickListener {
val args = Bundle().apply {
putBoolean(IS_UNDER_16, isUnder16)
putString(USER_NAME_ARG, "Aditya")
}
findNavController().navigate(R.id.action_signUpFragment_to_getMoreInfoFragment, args)
}
}
}
}

View File

@@ -0,0 +1,66 @@
package com.woka.onboard.fragments
import android.media.MediaPlayer
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import com.woka.R
import com.woka.databinding.FragmentSplashBinding
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
/*
Root fragment to the launcher activity i.e. WelcomeActivity
*/
class SplashFragment : Fragment() {
private lateinit var binding: FragmentSplashBinding
private var player: MediaPlayer? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentSplashBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
playBgMusic()
animateLogo()
lifecycleScope.launch {
delay(6000)
val extras = FragmentNavigatorExtras(binding.logo to "logo")
findNavController().navigate(R.id.action_splashFragment_to_languageFragment,
null, null, extras)
}
}
private fun playBgMusic() {
player = MediaPlayer.create(requireContext(), R.raw.audioone)
player?.start()
}
private fun animateLogo() {
binding.logo.animate().scaleXBy(1f).scaleYBy(1f)
.setDuration(2000)
.start()
}
override fun onDestroyView() {
super.onDestroyView()
player?.stop()
player?.release()
player = null
}
}

View File

@@ -0,0 +1,3 @@
package com.woka.onboard.models
data class Interest(val id: Int, val topic_name: String?)

View File

@@ -0,0 +1,19 @@
package com.woka.userPreference
import android.content.Context
import android.content.Context.MODE_PRIVATE
import android.content.SharedPreferences
class UserPreference(context: Context) {
companion object{
private const val USER_PREFERENCE = "woka_user_preferences"
private const val APP_LANGUAGE = "app_language"
}
private val userPrefs: SharedPreferences = context.getSharedPreferences(USER_PREFERENCE, MODE_PRIVATE)
var appLanguage: String
get() = userPrefs.getString(APP_LANGUAGE, "en")?:"en"
set(value) = userPrefs.edit().putString(APP_LANGUAGE, value).apply()
}

View File

@@ -0,0 +1,42 @@
package com.woka.utils
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.inputmethod.InputMethodManager
import com.woka.WokaApp.Companion.userPrefs
import java.util.Locale
fun View.show(){
this.visibility = VISIBLE
}
fun View.hide(){
this.visibility = GONE
}
fun Context.changeLocale(language: String){
val locale = Locale(language)
Locale.setDefault(locale)
val config: Configuration = this.resources.configuration
config.locale = locale
config.setLayoutDirection(locale)
this.resources.updateConfiguration(
config,
this.resources.displayMetrics
)
// saving to user preferences
userPrefs?.appLanguage = language
}
fun Activity.closeKeyboard(){
this.currentFocus?.let {
(this.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
.hideSoftInputFromWindow(it.windowToken, 0)
}
}

View File

@@ -0,0 +1,5 @@
package com.woka.utils
enum class Gender(value: Int){
MALE(0), FEMALE(1), NONE(-1)
}

View File

@@ -0,0 +1 @@
package com.woka.utils

View File

@@ -0,0 +1,23 @@
package com.woka.utils
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import com.woka.WokaApp.Companion.userPrefs
import kotlin.math.min
/*
Every activity in this application should extend to this Activity
to establish common configurations to every activity
*/
open class WokaBaseActivity: AppCompatActivity() {
override fun attachBaseContext(newBase: Context?) {
val configuration = Configuration(newBase?.resources?.configuration)
configuration.fontScale = min(configuration.fontScale.toDouble(), 1.0).toFloat()
applyOverrideConfiguration(configuration)
super.attachBaseContext(newBase)
changeLocale(userPrefs?.appLanguage?:"en")
}
}