diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 04991d8..a5c1501 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -4,6 +4,18 @@ + + + + + + + + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 726026e..728b9b3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,10 +16,15 @@ android:theme="@style/Theme.Woka" tools:targetApi="31"> + android:name=".home.sidebar.support.SupportActivity" + android:exported="false" + android:screenOrientation="portrait" /> + - val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom) - insets - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/sidebar/AboutActivity.kt b/app/src/main/java/com/woka/home/sidebar/aboutwoka/AboutActivity.kt similarity index 97% rename from app/src/main/java/com/woka/home/sidebar/AboutActivity.kt rename to app/src/main/java/com/woka/home/sidebar/aboutwoka/AboutActivity.kt index e45b839..db54884 100644 --- a/app/src/main/java/com/woka/home/sidebar/AboutActivity.kt +++ b/app/src/main/java/com/woka/home/sidebar/aboutwoka/AboutActivity.kt @@ -1,4 +1,4 @@ -package com.woka.home.sidebar +package com.woka.home.sidebar.aboutwoka import android.os.Bundle import android.transition.Slide diff --git a/app/src/main/java/com/woka/home/sidebar/faqs/FaqActivity.kt b/app/src/main/java/com/woka/home/sidebar/faqs/FaqActivity.kt new file mode 100644 index 0000000..e3f3599 --- /dev/null +++ b/app/src/main/java/com/woka/home/sidebar/faqs/FaqActivity.kt @@ -0,0 +1,80 @@ +package com.woka.home.sidebar.faqs + +import android.os.Bundle +import android.transition.Slide +import android.view.Gravity +import androidx.activity.enableEdgeToEdge +import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import com.woka.R +import com.woka.databinding.ActivityFaqBinding +import com.woka.modules.faqs.FAQsRepository +import com.woka.networking.ApiResult +import com.woka.utils.ProgressView +import com.woka.utils.toast + +class FaqActivity : AppCompatActivity() { + + private lateinit var binding: ActivityFaqBinding + + private var adapter: FaqsAdapter? = null + private lateinit var progressView: ProgressView + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + window.enterTransition = Slide().apply { + slideEdge = Gravity.END + } + enableEdgeToEdge() + binding = ActivityFaqBinding.inflate(layoutInflater) + setContentView(binding.root) + 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 + } + + progressView = ProgressView(this, getString(R.string.please_wait)) + + initViews() + + clickEvents() + + setObservers() + } + + private fun setObservers() { + FAQsRepository.faqLiveData.observe(this){ + when(it){ + is ApiResult.Error -> { + toast(it.errorMessage) + progressView.hide() + } + is ApiResult.Loading -> progressView.show() + is ApiResult.Success -> { + progressView.hide() + it.data?.result?.let {faqs -> + adapter?.submitList(faqs) + } + } + null -> {} + } + } + } + + private fun initViews() { + binding.apply { + adapter = FaqsAdapter() + rvFaq.adapter = adapter + } + } + + private fun clickEvents() { + binding.apply { + backBtn.setOnClickListener { + onBackPressedDispatcher.onBackPressed() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/sidebar/faqs/FaqsAdapter.kt b/app/src/main/java/com/woka/home/sidebar/faqs/FaqsAdapter.kt new file mode 100644 index 0000000..a81b51e --- /dev/null +++ b/app/src/main/java/com/woka/home/sidebar/faqs/FaqsAdapter.kt @@ -0,0 +1,90 @@ +package com.woka.home.sidebar.faqs + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.core.content.res.ResourcesCompat +import androidx.core.view.isVisible +import androidx.recyclerview.widget.AsyncDifferConfig +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView.ViewHolder +import com.woka.R +import com.woka.databinding.FaqViewHolderBinding +import com.woka.modules.faqs.models.Faq +import com.woka.utils.hide +import com.woka.utils.show +import java.util.concurrent.Executors + +class FaqsAdapter(config: AsyncDifferConfig) : + ListAdapter(config) { + + inner class FaqViewHolder(val binding: FaqViewHolderBinding): ViewHolder(binding.root) + + private var openedFaq = -1 + + companion object{ + private val DIFF_UTILS = object : DiffUtil.ItemCallback(){ + override fun areItemsTheSame(oldItem: Faq, newItem: Faq): Boolean = + oldItem.id == newItem.id + + override fun areContentsTheSame(oldItem: Faq, newItem: Faq): Boolean = + oldItem == newItem + } + + private val ASYNC_DIFF_CONFIG = AsyncDifferConfig.Builder(DIFF_UTILS) + .setBackgroundThreadExecutor(Executors.newSingleThreadExecutor()) + .build() + } + + constructor(): this(ASYNC_DIFF_CONFIG) + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FaqViewHolder { + return FaqViewHolder(FaqViewHolderBinding.inflate(LayoutInflater.from(parent.context), parent, false)) + } + + override fun onBindViewHolder(holder: FaqViewHolder, position: Int) { + val faq = getItem(position) + + holder.binding.apply { + title.text = faq.english_question + description.text = faq.english_answer + + val arrowUp = ResourcesCompat.getDrawable(card.context.resources, R.drawable.ic_half_arrow_up, null) + val arrowRight = ResourcesCompat.getDrawable(card.context.resources, R.drawable.ic_half_arrow_right, null) + + if (position == openedFaq){ + // showing + descriptionView.show() + title.setCompoundDrawablesWithIntrinsicBounds(null, null, arrowUp, null) + }else{ + // not showing + descriptionView.hide() + title.setCompoundDrawablesWithIntrinsicBounds(null, null, arrowRight, null) + } + + card.setOnClickListener { + + if (descriptionView.isVisible){ + // closing the faq + descriptionView.hide() + title.setCompoundDrawablesWithIntrinsicBounds(null, null, arrowRight, null) + }else{ + // closing previous faq + if (openedFaq != -1){ + try { + notifyItemChanged(openedFaq) + } catch (e: Exception) { + // do nothing + } + } + // opening the faq + descriptionView.show() + title.setCompoundDrawablesWithIntrinsicBounds(null, null, arrowUp, null) + + openedFaq = position + } + + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/sidebar/support/SupportActivity.kt b/app/src/main/java/com/woka/home/sidebar/support/SupportActivity.kt new file mode 100644 index 0000000..8092125 --- /dev/null +++ b/app/src/main/java/com/woka/home/sidebar/support/SupportActivity.kt @@ -0,0 +1,162 @@ +package com.woka.home.sidebar.support + +import android.os.Bundle +import android.transition.Slide +import android.util.Patterns +import android.view.Gravity +import android.widget.ArrayAdapter +import androidx.activity.enableEdgeToEdge +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.lifecycle.ViewModelProvider +import com.woka.R +import com.woka.WokaApp.Companion.userPrefs +import com.woka.databinding.ActivitySupportBinding +import com.woka.networking.ApiResult +import com.woka.utils.ProgressView +import com.woka.utils.UserType +import com.woka.utils.WokaBaseActivity +import com.woka.utils.hide +import com.woka.utils.toast + + +class SupportActivity : WokaBaseActivity() { + + private lateinit var binding: ActivitySupportBinding + private lateinit var viewModel: SupportViewModel + + private lateinit var progressView: ProgressView + + private val subjects = arrayOf( + "Select a subject", "Query", + "Complaint", "Suggestion", "Other" + ) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + window.enterTransition = Slide().apply { + slideEdge = Gravity.END + } + enableEdgeToEdge() + binding = ActivitySupportBinding.inflate(layoutInflater) + setContentView(binding.root) + 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 + } + + viewModel = ViewModelProvider(this)[SupportViewModel::class.java] + progressView = ProgressView(this, getString(R.string.please_wait)) + + initViews() + + clickEvents() + + setObservers() + } + + private fun setObservers() { + viewModel.supportLiveData.observe(this){ + when(it){ + is ApiResult.Error -> { + progressView.hide() + toast(it.errorMessage) + } + is ApiResult.Loading -> progressView.show() + is ApiResult.Success -> { + progressView.hide() + toast(it.message) + } + null -> {} + } + } + } + + private fun initViews() { + binding.apply { + + if (userPrefs?.userType != UserType.GUEST){ + // user is logged in + nameView.hide() + emailView.hide() + } + + val adapter: ArrayAdapter<*> = ArrayAdapter( + this@SupportActivity, + android.R.layout.simple_spinner_item, + subjects.toList() + ) + + adapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item + ) + + subjectSpinner.setAdapter(adapter) + } + } + + private fun clickEvents() { + binding.apply { + backBtn.setOnClickListener { + onBackPressedDispatcher.onBackPressed() + } + + submit.setOnClickListener { + if (allOkay()){ + binding.apply { + if (userPrefs?.userType == UserType.GUEST){ + viewModel.supportForGuest( + email.text.toString(), + name.text.toString(), + subjectSpinner.selectedItem.toString(), + message.text.toString() + ) + }else{ + viewModel.supportForUser( + userPrefs?.userData?.id.toString(), + subjectSpinner.selectedItem.toString(), + message.text.toString() + ) + } + } + } + } + } + } + + private fun allOkay(): Boolean { + var allOkay = true + + binding.apply { + + name.error = null + email.error = null + message.error = null + + if (userPrefs?.userType == UserType.GUEST){ + if (name.text.isEmpty()){ + name.error = getString(R.string.required) + allOkay = false + } + + if (!Patterns.EMAIL_ADDRESS.matcher(email.text).matches()){ + email.error = getString(R.string.invalid_email) + allOkay = false + } + } + + if (subjectSpinner.selectedItemId == 0L){ + toast("Please select a subject") + allOkay = false + } + + if (message.text.isEmpty()){ + message.error = getString(R.string.required) + allOkay = false + } + } + + return allOkay + } +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/sidebar/support/SupportViewModel.kt b/app/src/main/java/com/woka/home/sidebar/support/SupportViewModel.kt new file mode 100644 index 0000000..7902a35 --- /dev/null +++ b/app/src/main/java/com/woka/home/sidebar/support/SupportViewModel.kt @@ -0,0 +1,40 @@ +package com.woka.home.sidebar.support + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.woka.modules.ModuleRepository +import com.woka.networking.ApiResult +import kotlinx.coroutines.launch + +class SupportViewModel: ViewModel() { + + private val _supportLiveData = MutableLiveData?>() + val supportLiveData: LiveData?> + get() = _supportLiveData + + fun supportForGuest(email: String, name: String, subject: String, message: String) { + viewModelScope.launch { + _supportLiveData.postValue(ApiResult.Loading()) + _supportLiveData.postValue(ModuleRepository.supportForGuest( + email, + name, + subject, + message + )) + } + } + + fun supportForUser(userId: String, subject: String, message: String) { + viewModelScope.launch { + _supportLiveData.postValue(ApiResult.Loading()) + _supportLiveData.postValue(ModuleRepository.supportForUser( + userId, + subject, + message + )) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/modules/ModuleApiService.kt b/app/src/main/java/com/woka/modules/ModuleApiService.kt index 3a47f42..070087c 100644 --- a/app/src/main/java/com/woka/modules/ModuleApiService.kt +++ b/app/src/main/java/com/woka/modules/ModuleApiService.kt @@ -3,7 +3,9 @@ package com.woka.modules import com.woka.modules.blogs.models.BlogsResponse import com.woka.modules.faqs.models.FaqResponse import com.woka.networking.ApiResponse +import okhttp3.FormBody import retrofit2.Response +import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST @@ -13,5 +15,11 @@ interface ModuleApiService { suspend fun getBlogs(): Response> @POST("faq_listing") - suspend fun getFaqs(): Response> + suspend fun getFaqs(@Body formBody: FormBody): Response> + + @POST("guest_queries_store") + suspend fun supportForGuest(@Body body: FormBody): Response> + + @POST("guest_queries_store") + suspend fun supportForUser(@Body body: FormBody): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/woka/modules/ModuleRepository.kt b/app/src/main/java/com/woka/modules/ModuleRepository.kt new file mode 100644 index 0000000..764aa62 --- /dev/null +++ b/app/src/main/java/com/woka/modules/ModuleRepository.kt @@ -0,0 +1,36 @@ +package com.woka.modules + +import com.woka.networking.ApiResult +import com.woka.networking.RetrofitHelper +import okhttp3.FormBody + +object ModuleRepository { + + private val moduleApiService = RetrofitHelper.getRetrofit().create(ModuleApiService::class.java) + + suspend fun supportForGuest(email: String, name: String, subject: String, message: String): ApiResult { + return RetrofitHelper.handleApiCall { + moduleApiService.supportForGuest( + FormBody.Builder() + .add("name", name) + .add("email_id", email) + .add("subject", subject) + .add("message", message) + .build() + ) + } + } + + suspend fun supportForUser(userId: String, subject: String, message: String): ApiResult { + return RetrofitHelper.handleApiCall { + moduleApiService.supportForGuest( + FormBody.Builder() + .add("user_id", userId) + .add("subject", subject) + .add("message", message) + .build() + ) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/woka/home/BlogsAdapter.kt b/app/src/main/java/com/woka/modules/blogs/BlogsAdapter.kt similarity index 98% rename from app/src/main/java/com/woka/home/BlogsAdapter.kt rename to app/src/main/java/com/woka/modules/blogs/BlogsAdapter.kt index 0ab5fb8..ae1b7ae 100644 --- a/app/src/main/java/com/woka/home/BlogsAdapter.kt +++ b/app/src/main/java/com/woka/modules/blogs/BlogsAdapter.kt @@ -1,4 +1,4 @@ -package com.woka.home +package com.woka.modules.blogs import android.view.LayoutInflater import android.view.ViewGroup diff --git a/app/src/main/java/com/woka/modules/faqs/FAQsRepository.kt b/app/src/main/java/com/woka/modules/faqs/FAQsRepository.kt index 6cfda2a..3f46b5d 100644 --- a/app/src/main/java/com/woka/modules/faqs/FAQsRepository.kt +++ b/app/src/main/java/com/woka/modules/faqs/FAQsRepository.kt @@ -9,6 +9,7 @@ import com.woka.networking.RetrofitHelper import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import okhttp3.FormBody object FAQsRepository { @@ -24,7 +25,11 @@ object FAQsRepository { private suspend fun getBlogs(): ApiResult { return RetrofitHelper.handleApiCall { - apiService.getFaqs() + apiService.getFaqs( + FormBody.Builder() + .add("faq_category_key", "watch") + .build() + ) } } diff --git a/app/src/main/java/com/woka/modules/faqs/models/Result.kt b/app/src/main/java/com/woka/modules/faqs/models/Faq.kt similarity index 91% rename from app/src/main/java/com/woka/modules/faqs/models/Result.kt rename to app/src/main/java/com/woka/modules/faqs/models/Faq.kt index 5ee236b..6c8ff2b 100644 --- a/app/src/main/java/com/woka/modules/faqs/models/Result.kt +++ b/app/src/main/java/com/woka/modules/faqs/models/Faq.kt @@ -1,6 +1,6 @@ package com.woka.modules.faqs.models -data class Result( +data class Faq( val category_master_id: Int?, val english_answer: String?, val english_question: String?, diff --git a/app/src/main/java/com/woka/modules/faqs/models/FaqResponse.kt b/app/src/main/java/com/woka/modules/faqs/models/FaqResponse.kt index 6090945..1853e0e 100644 --- a/app/src/main/java/com/woka/modules/faqs/models/FaqResponse.kt +++ b/app/src/main/java/com/woka/modules/faqs/models/FaqResponse.kt @@ -1,6 +1,6 @@ package com.woka.modules.faqs.models data class FaqResponse( - val result: List?, + val result: List?, val total_records: Int? ) \ No newline at end of file diff --git a/app/src/main/java/com/woka/userPreference/UserPreference.kt b/app/src/main/java/com/woka/userPreference/UserPreference.kt index 90c1a4c..5c78152 100644 --- a/app/src/main/java/com/woka/userPreference/UserPreference.kt +++ b/app/src/main/java/com/woka/userPreference/UserPreference.kt @@ -37,6 +37,8 @@ class UserPreference(context: Context) { @SuppressLint("HardwareIds") val deviceId: String = Secure.getString(context.contentResolver, Secure.ANDROID_ID) + var userData: UserData? = null + var appLanguage: String get() = userPrefs.getString(APP_LANGUAGE, "en") ?: "en" set(value) = userPrefs.edit().putString(APP_LANGUAGE, value).apply() @@ -66,7 +68,15 @@ class UserPreference(context: Context) { fun loadUserData() { CoroutineScope(Dispatchers.IO).launch { _userLiveData.postValue(ApiResult.Loading()) - _userLiveData.postValue(userRepository.getUserData()) + val result = userRepository.getUserData() + + when (result){ + is ApiResult.Error -> {} + is ApiResult.Loading -> {} + is ApiResult.Success -> userData = result.data?.result + } + + _userLiveData.postValue(result) } } diff --git a/app/src/main/res/drawable-hdpi/img_support.png b/app/src/main/res/drawable-hdpi/img_support.png new file mode 100644 index 0000000..ddac04f Binary files /dev/null and b/app/src/main/res/drawable-hdpi/img_support.png differ diff --git a/app/src/main/res/drawable-ldpi/img_support.png b/app/src/main/res/drawable-ldpi/img_support.png new file mode 100644 index 0000000..d1ad027 Binary files /dev/null and b/app/src/main/res/drawable-ldpi/img_support.png differ diff --git a/app/src/main/res/drawable-mdpi/img_support.png b/app/src/main/res/drawable-mdpi/img_support.png new file mode 100644 index 0000000..28f134b Binary files /dev/null and b/app/src/main/res/drawable-mdpi/img_support.png differ diff --git a/app/src/main/res/drawable-xhdpi/img_support.png b/app/src/main/res/drawable-xhdpi/img_support.png new file mode 100644 index 0000000..5f88336 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/img_support.png differ diff --git a/app/src/main/res/drawable-xxhdpi/img_support.png b/app/src/main/res/drawable-xxhdpi/img_support.png new file mode 100644 index 0000000..0684cc0 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/img_support.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/img_support.png b/app/src/main/res/drawable-xxxhdpi/img_support.png new file mode 100644 index 0000000..c9c9d69 Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/img_support.png differ diff --git a/app/src/main/res/drawable/ic_half_arrow_right.xml b/app/src/main/res/drawable/ic_half_arrow_right.xml new file mode 100644 index 0000000..8149240 --- /dev/null +++ b/app/src/main/res/drawable/ic_half_arrow_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_half_arrow_up.xml b/app/src/main/res/drawable/ic_half_arrow_up.xml new file mode 100644 index 0000000..78a9ddd --- /dev/null +++ b/app/src/main/res/drawable/ic_half_arrow_up.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/support_bg.xml b/app/src/main/res/drawable/support_bg.xml new file mode 100644 index 0000000..f67badb --- /dev/null +++ b/app/src/main/res/drawable/support_bg.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 8913e28..b56ec29 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -6,7 +6,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/about_bg" - tools:context=".home.sidebar.AboutActivity"> + tools:context=".home.sidebar.aboutwoka.AboutActivity"> + tools:context=".home.sidebar.faqs.FaqActivity"> + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_home.xml b/app/src/main/res/layout/activity_home.xml index 4fa598a..0321101 100644 --- a/app/src/main/res/layout/activity_home.xml +++ b/app/src/main/res/layout/activity_home.xml @@ -408,43 +408,49 @@ - - android:text="@string/faqs" - android:fontFamily="@font/exo_2_bold" - android:textColor="@color/white" - android:textSize="@dimen/_14ssp" + - android:foreground="?android:attr/selectableItemBackground" - /> + - - android:text="@string/woka_support" - android:fontFamily="@font/exo_2_bold" - android:textColor="@color/white" - android:textSize="@dimen/_14ssp" + - android:foreground="?android:attr/selectableItemBackground" - /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +