Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #659: Lowfi admin control part 3 logout appversion #755

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
android:name=".administratorcontrols.AdministratorControlsActivity"
android:screenOrientation="portrait"
android:theme="@style/OppiaThemeWithoutActionBar" />
<activity
android:name=".administratorcontrols.appversion.AppVersionActivity"
android:screenOrientation="portrait"
android:theme="@style/OppiaThemeWithoutActionBar"/>
<activity
android:name=".help.faq.FAQActivity"
android:screenOrientation="portrait"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.oppia.app.profile.AdminPinActivity
import org.oppia.app.profile.PinPasswordActivity
import org.oppia.app.profile.ProfileActivity
import org.oppia.app.administratorcontrols.AdministratorControlsActivity
import org.oppia.app.administratorcontrols.appversion.AppVersionActivity
import org.oppia.app.help.faq.FAQActivity
import org.oppia.app.settings.profile.ProfileEditActivity
import org.oppia.app.settings.profile.ProfileListActivity
Expand Down Expand Up @@ -63,6 +64,7 @@ interface ActivityComponent {
fun inject(adminAuthActivity: AdminAuthActivity)
fun inject(administratorControlsActivity: AdministratorControlsActivity)
fun inject(adminPinActivity: AdminPinActivity)
fun inject(appVersionActivity: AppVersionActivity)
fun inject(appLanguageActivity: AppLanguageActivity)
fun inject(audioFragmentTestActivity: AudioFragmentTestActivity)
fun inject(bindableAdapterTestActivity: BindableAdapterTestActivity)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import android.os.Bundle
import android.view.Menu
import org.oppia.app.R
import org.oppia.app.activity.InjectableAppCompatActivity
import org.oppia.app.administratorcontrols.appversion.AppVersionActivity
import org.oppia.app.drawer.KEY_NAVIGATION_PROFILE_ID
import javax.inject.Inject

/** Activity for Administrator Controls. */
class AdministratorControlsActivity : InjectableAppCompatActivity() {
class AdministratorControlsActivity : InjectableAppCompatActivity(), RouteToAppVersionListener {
@Inject lateinit var administratorControlsActivityPresenter: AdministratorControlsActivityPresenter

override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -25,6 +26,10 @@ class AdministratorControlsActivity : InjectableAppCompatActivity() {
return super.onCreateOptionsMenu(menu)
}

override fun routeToAppVersion() {
startActivity(AppVersionActivity.createAppVersionActivityIntent(this))
}

companion object {
fun createAdministratorControlsActivityIntent(context: Context, profileId: Int?): Intent {
val intent = Intent(context, AdministratorControlsActivity::class.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
package org.oppia.app.administratorcontrols

import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.ObservableList
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsAccountActionsViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsAppInformationViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsDownloadPermissionsViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsGeneralViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsProfileViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsItemViewModel
import org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel.AdministratorControlsProfileViewModel
import org.oppia.app.fragment.FragmentScope
import org.oppia.app.viewmodel.ObservableArrayList
import org.oppia.app.viewmodel.ObservableViewModel
import javax.inject.Inject

/** [ViewModel] for [AdministratorControlsFragment]. */
@FragmentScope
class AdministratorControlsViewModel @Inject constructor() : ObservableViewModel() {
class AdministratorControlsViewModel @Inject constructor(
private val activity: AppCompatActivity,
private val fragment: Fragment
) : ObservableViewModel() {
private val itemViewModelList: ObservableList<AdministratorControlsItemViewModel> = ObservableArrayList()

fun processAdministratorControlsList(): ObservableList<AdministratorControlsItemViewModel> {
itemViewModelList.add(AdministratorControlsGeneralViewModel())
itemViewModelList.add(AdministratorControlsProfileViewModel())
itemViewModelList.add(AdministratorControlsDownloadPermissionsViewModel())
itemViewModelList.add(AdministratorControlsAppInformationViewModel())
itemViewModelList.add(AdministratorControlsAccountActionsViewModel())
itemViewModelList.add(AdministratorControlsAppInformationViewModel(activity))
itemViewModelList.add(AdministratorControlsAccountActionsViewModel(fragment))

return itemViewModelList
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.oppia.app.administratorcontrols

/** Listener for when an activity should route to App Version. */
interface RouteToAppVersionListener {
fun routeToAppVersion()
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
package org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel

import android.content.Intent
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import org.oppia.app.R
import org.oppia.app.profile.ProfileActivity

/** [ViewModel] for the recycler view in [AdministratorControlsFragment]. */
class AdministratorControlsAccountActionsViewModel : AdministratorControlsItemViewModel()
class AdministratorControlsAccountActionsViewModel(
private val fragment: Fragment
) : AdministratorControlsItemViewModel() {

fun onLogOutClicked() {
AlertDialog.Builder(fragment.context!!, R.style.AlertDialogTheme)
.setMessage(R.string.log_out_dialog_message)
.setNegativeButton(R.string.log_out_dialog_cancel_button) { dialog, _ ->
dialog.dismiss()
}
.setPositiveButton(R.string.log_out_dialog_okay_button) { _, _ ->
// TODO(#762): Replace ProfileActivity to LoginActivity once it is added.
val intent = Intent(fragment.activity, ProfileActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
fragment.activity!!.startActivity(intent)
fragment.activity!!.finish()
}.create().show()
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
package org.oppia.app.administratorcontrols.administratorcontrolsitemviewmodel

import androidx.appcompat.app.AppCompatActivity
import org.oppia.app.administratorcontrols.RouteToAppVersionListener

/** [ViewModel] for the recycler view in [AdministratorControlsFragment]. */
class AdministratorControlsAppInformationViewModel : AdministratorControlsItemViewModel()
class AdministratorControlsAppInformationViewModel(
activity: AppCompatActivity
) : AdministratorControlsItemViewModel() {

private val routeToAppVersionListener = activity as RouteToAppVersionListener

fun onAppVersionClicked() {
routeToAppVersionListener.routeToAppVersion()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.oppia.app.administratorcontrols.appversion

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.MenuItem
import org.oppia.app.activity.InjectableAppCompatActivity
import javax.inject.Inject

/** Activity for App Version. */
class AppVersionActivity : InjectableAppCompatActivity() {
@Inject lateinit var appVersionActivityPresenter: AppVersionActivityPresenter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityComponent.inject(this)
appVersionActivityPresenter.handleOnCreate()
}

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
if (item?.itemId == android.R.id.home) {
onBackPressed()
}
return super.onOptionsItemSelected(item)
}

companion object {
fun createAppVersionActivityIntent(context: Context): Intent {
return Intent(context, AppVersionActivity::class.java)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.oppia.app.administratorcontrols.appversion

import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import org.oppia.app.R
import org.oppia.app.activity.ActivityScope
import javax.inject.Inject

/** The presenter for [AppVersionActivity]. */
@ActivityScope
class AppVersionActivityPresenter @Inject constructor(private val activity: AppCompatActivity) {
fun handleOnCreate() {
activity.setContentView(R.layout.app_version_activity)
setToolbar()
if (getAppVersionFragment() == null) {
activity.supportFragmentManager.beginTransaction().add(
R.id.app_version_fragment_placeholder,
AppVersionFragment()
).commitNow()
}
}

private fun setToolbar() {
val appVersionToolbar: Toolbar = activity.findViewById(R.id.app_version_toolbar) as Toolbar
activity.setSupportActionBar(appVersionToolbar)
activity.supportActionBar?.setDisplayHomeAsUpEnabled(true)
}

private fun getAppVersionFragment(): AppVersionFragment? {
return activity.supportFragmentManager.findFragmentById(R.id.app_version_fragment_placeholder) as AppVersionFragment?
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.oppia.app.administratorcontrols.appversion

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import org.oppia.app.fragment.InjectableFragment
import javax.inject.Inject

/** Fragment that contains app version and last update time of the Oppia application. */
class AppVersionFragment : InjectableFragment(){
@Inject lateinit var appVersionFragmentPresenter: AppVersionFragmentPresenter

override fun onAttach(context: Context) {
super.onAttach(context)
fragmentComponent.inject(this)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return appVersionFragmentPresenter.handleCreateView(inflater, container)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.oppia.app.administratorcontrols.appversion

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import org.oppia.app.databinding.AppVersionFragmentBinding
import org.oppia.app.fragment.FragmentScope
import org.oppia.app.viewmodel.ViewModelProvider
import javax.inject.Inject

/** The presenter for [AppVersionFragment]. */
@FragmentScope
class AppVersionFragmentPresenter @Inject constructor(
private val fragment: Fragment,
private val viewModelProvider: ViewModelProvider<AppVersionViewModel>
) {
private lateinit var binding: AppVersionFragmentBinding

fun handleCreateView(inflater: LayoutInflater, container: ViewGroup?): View? {
binding = AppVersionFragmentBinding.inflate(inflater, container, /* attachToRoot= */ false)
binding.let {
it.lifecycleOwner = fragment
it.viewModel = getAppVersionViewModel()
}
return binding.root
}

private fun getAppVersionViewModel(): AppVersionViewModel {
return viewModelProvider.getForFragment(fragment, AppVersionViewModel::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.oppia.app.administratorcontrols.appversion

import androidx.databinding.ObservableField
import androidx.fragment.app.Fragment
import org.oppia.app.BuildConfig
import org.oppia.app.fragment.FragmentScope
import org.oppia.app.viewmodel.ObservableViewModel
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject

/** [ViewModel] for [AppVersionFragment]*/
@FragmentScope
class AppVersionViewModel @Inject constructor(
fragment: Fragment
) : ObservableViewModel() {

val versionName = ObservableField<String>(BuildConfig.VERSION_NAME)

private val lastUpdateDateTime =
fragment.activity!!.packageManager.getPackageInfo(fragment.activity!!.packageName, /* flags= */ 0).lastUpdateTime
val lastUpdateDate = ObservableField<String>(getDateTime(lastUpdateDateTime))

// TODO(#555): Create one central utility file from where we should access date format or even convert date timestamp to string from that file.
private fun getDateTime(l: Long): String? {
return try {
val sdf = SimpleDateFormat("dd MMMM yyyy", Locale.US)
val netDate = Date(l)
sdf.format(netDate)
} catch (e: Exception) {
e.toString()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import org.oppia.app.profile.AdminSettingsDialogFragment
import org.oppia.app.profile.ProfileChooserFragment
import org.oppia.app.profile.ResetPinDialogFragment
import org.oppia.app.administratorcontrols.AdministratorControlsFragment
import org.oppia.app.administratorcontrols.appversion.AppVersionFragment
import org.oppia.app.help.faq.FAQFragment
import org.oppia.app.story.StoryFragment
import org.oppia.app.testing.BindableAdapterTestFragment
Expand Down Expand Up @@ -51,6 +52,7 @@ interface FragmentComponent {

fun inject(administratorControlsFragment: AdministratorControlsFragment)
fun inject(adminSettingsDialogFragment: AdminSettingsDialogFragment)
fun inject(appVersionFragment: AppVersionFragment)
fun inject(audioFragment: AudioFragment)
fun inject(bindableAdapterTestFragment: BindableAdapterTestFragment)
fun inject(conceptCardFragment: ConceptCardFragment)
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_info_icon_gray_24dp.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#999999"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z" />
</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
android:paddingRight="16dp"
android:paddingBottom="20dp"
android:text="@string/administrator_controls_log_out"
android:onClick="@{(v) -> viewModel.onLogOutClicked()}"
android:textColor="@color/oppiaPrimaryTextDark"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
android:paddingRight="16dp"
android:paddingBottom="20dp"
android:text="@string/administrator_controls_app_version"
android:onClick="@{(v) -> viewModel.onAppVersionClicked()}"
android:textColor="@color/oppiaPrimaryTextDark"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
Expand Down
40 changes: 40 additions & 0 deletions app/src/main/res/layout/app_version_activity.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".administratorcontrols.appversion.AppVersionActivity">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/app_version_app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<androidx.appcompat.widget.Toolbar
android:id="@+id/app_version_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/oppiaPrimaryDark"
android:textSize="20sp"
app:navigationContentDescription="@string/go_to_previous_page"
app:navigationIcon="?attr/homeAsUpIndicator"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:title="@string/administrator_controls_app_version"
app:titleTextColor="@color/white" />
</com.google.android.material.appbar.AppBarLayout>

<FrameLayout
android:id="@+id/app_version_fragment_placeholder"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/app_version_app_bar_layout"
app:layout_constraintVertical_weight="1" />
</androidx.constraintlayout.widget.ConstraintLayout>
Loading