diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index f8eb4b8de0..fcace5066b 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3226,4 +3226,13 @@ Verified · Last activity %1$s Unverified · Last activity %1$s + Welcome to a new view! + To simplify your Element, tabs are now optional. Manage them using the top-right menu. + Access Spaces + Access your Spaces (bottom-right) faster and easier than ever before. + Give Feedback + Tap top right to see the option to feedback. + Read more + Try it out + diff --git a/library/ui-styles/src/main/res/values-h720dp/dimens.xml b/library/ui-styles/src/main/res/values-h720dp/dimens.xml index 1a7791720d..2a7b12cf2f 100644 --- a/library/ui-styles/src/main/res/values-h720dp/dimens.xml +++ b/library/ui-styles/src/main/res/values-h720dp/dimens.xml @@ -2,4 +2,8 @@ 0.05 0.40 - \ No newline at end of file + + 16dp + 40dp + 46dp + diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml index 53f1044a12..758dd6e978 100644 --- a/library/ui-styles/src/main/res/values/dimens.xml +++ b/library/ui-styles/src/main/res/values/dimens.xml @@ -74,4 +74,9 @@ 112dp + + + 8dp + 16dp + 28dp diff --git a/vector/src/main/AndroidManifest.xml b/vector/src/main/AndroidManifest.xml index e87bbad77a..c4022576c3 100644 --- a/vector/src/main/AndroidManifest.xml +++ b/vector/src/main/AndroidManifest.xml @@ -338,6 +338,7 @@ + diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt index b21b4778e3..a40aeaaa15 100644 --- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt @@ -53,6 +53,7 @@ import im.vector.app.features.home.room.detail.upgrade.MigrateRoomViewModel import im.vector.app.features.home.room.list.RoomListViewModel import im.vector.app.features.home.room.list.home.HomeRoomListViewModel import im.vector.app.features.home.room.list.home.invites.InvitesViewModel +import im.vector.app.features.home.room.list.home.release.ReleaseNotesViewModel import im.vector.app.features.homeserver.HomeServerCapabilitiesViewModel import im.vector.app.features.invite.InviteUsersToRoomViewModel import im.vector.app.features.location.LocationSharingViewModel @@ -624,4 +625,9 @@ interface MavericksViewModelModule { @IntoMap @MavericksViewModelKey(InvitesViewModel::class) fun invitesViewModel(factory: InvitesViewModel.Factory): MavericksAssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @MavericksViewModelKey(ReleaseNotesViewModel::class) + fun releaseNotesViewModel(factory: ReleaseNotesViewModel.Factory): MavericksAssistedViewModelFactory<*, *> } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 2a8390c93c..78b4364f38 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -60,6 +60,7 @@ import im.vector.app.features.disclaimer.showDisclaimerDialog import im.vector.app.features.home.room.list.actions.RoomListSharedAction import im.vector.app.features.home.room.list.actions.RoomListSharedActionViewModel import im.vector.app.features.home.room.list.home.layout.HomeLayoutSettingBottomDialogFragment +import im.vector.app.features.home.room.list.home.release.ReleaseNotesActivity import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.matrixto.OriginOfMatrixTo import im.vector.app.features.navigation.Navigator @@ -268,6 +269,7 @@ class HomeActivity : } is HomeActivityViewEvents.OnCrossSignedInvalidated -> handleCrossSigningInvalidated(it) HomeActivityViewEvents.ShowAnalyticsOptIn -> handleShowAnalyticsOptIn() + HomeActivityViewEvents.ShowReleaseNotes -> handleShowReleaseNotes() HomeActivityViewEvents.NotifyUserForThreadsMigration -> handleNotifyUserForThreadsMigration() is HomeActivityViewEvents.MigrateThreads -> migrateThreadsIfNeeded(it.checkSession) } @@ -282,6 +284,10 @@ class HomeActivity : homeActivityViewModel.handle(HomeActivityViewActions.ViewStarted) } + private fun handleShowReleaseNotes() { + startActivity(Intent(this, ReleaseNotesActivity::class.java)) + } + private fun showSpaceSettings(spaceId: String) { // open bottom sheet SpaceSettingsMenuBottomSheet diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt index 170550d5b4..e0b9e8ceb5 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewEvents.kt @@ -31,6 +31,7 @@ sealed interface HomeActivityViewEvents : VectorViewEvents { data class OnCrossSignedInvalidated(val userItem: MatrixItem.UserItem) : HomeActivityViewEvents object PromptToEnableSessionPush : HomeActivityViewEvents object ShowAnalyticsOptIn : HomeActivityViewEvents + object ShowReleaseNotes : HomeActivityViewEvents object NotifyUserForThreadsMigration : HomeActivityViewEvents data class MigrateThreads(val checkSession: Boolean) : HomeActivityViewEvents object StartRecoverySetupFlow : HomeActivityViewEvents diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index cfe76706a5..02648e77fc 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -31,6 +31,7 @@ import im.vector.app.features.analytics.AnalyticsTracker import im.vector.app.features.analytics.extensions.toAnalyticsType import im.vector.app.features.analytics.plan.Signup import im.vector.app.features.analytics.store.AnalyticsStore +import im.vector.app.features.home.room.list.home.release.ReleaseNotesPreferencesStore import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.onboarding.AuthenticationDescription import im.vector.app.features.raw.wellknown.ElementWellKnown @@ -82,6 +83,7 @@ class HomeActivityViewModel @AssistedInject constructor( private val vectorPreferences: VectorPreferences, private val analyticsTracker: AnalyticsTracker, private val analyticsConfig: AnalyticsConfig, + private val releaseNotesPreferencesStore: ReleaseNotesPreferencesStore ) : VectorViewModel(initialState) { @AssistedFactory @@ -110,9 +112,19 @@ class HomeActivityViewModel @AssistedInject constructor( checkSessionPushIsOn() observeCrossSigningReset() observeAnalytics() + observeReleaseNotes() initThreadsMigration() } + private fun observeReleaseNotes() { + releaseNotesPreferencesStore.appLayoutOnboardingShown.onEach { isAppLayoutOnboardingShown -> + if (!isAppLayoutOnboardingShown) { + _viewEvents.post(HomeActivityViewEvents.ShowReleaseNotes) + releaseNotesPreferencesStore.setAppLayoutOnboardingShown(true) + } + }.launchIn(viewModelScope) + } + private fun observeAnalytics() { if (analyticsConfig.isEnabled) { analyticsStore.didAskUserConsentFlow diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseCarouselData.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseCarouselData.kt new file mode 100644 index 0000000000..22431b0bf9 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseCarouselData.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes + +class ReleaseCarouselData( + val items: List +) { + data class Item( + @StringRes val title: Int, + @StringRes val body: Int, + @DrawableRes val image: Int, + ) +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseCarouselItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseCarouselItem.kt new file mode 100644 index 0000000000..49eb0761f7 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseCarouselItem.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import android.widget.ImageView +import android.widget.TextView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.VectorEpoxyHolder +import im.vector.app.core.epoxy.VectorEpoxyModel + +@EpoxyModelClass +abstract class ReleaseCarouselItem : VectorEpoxyModel(R.layout.item_release_carousel) { + + @EpoxyAttribute + lateinit var item: ReleaseCarouselData.Item + + override fun bind(holder: Holder) { + super.bind(holder) + + holder.image.setImageResource(item.image) + holder.title.setText(item.title) + holder.body.setText(item.body) + } + + class Holder : VectorEpoxyHolder() { + val image by bind(R.id.carousel_item_image) + val title by bind(R.id.carousel_item_title) + val body by bind(R.id.carousel_item_body) + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesAction.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesAction.kt new file mode 100644 index 0000000000..7a66d00589 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesAction.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class ReleaseNotesAction : VectorViewModelAction { + data class NextPressed( + val isLastItemSelected: Boolean = false + ) : ReleaseNotesAction() + data class PageSelected( + val selectedPageIndex: Int = 0 + ) : ReleaseNotesAction() +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt new file mode 100644 index 0000000000..c5cc55d7bb --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesActivity.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.core.extensions.addFragment +import im.vector.app.core.platform.ScreenOrientationLocker +import im.vector.app.core.platform.VectorBaseActivity +import im.vector.app.databinding.ActivitySimpleBinding +import javax.inject.Inject + +@AndroidEntryPoint +class ReleaseNotesActivity : VectorBaseActivity() { + + @Inject lateinit var orientationLocker: ScreenOrientationLocker + + override fun getBinding() = ActivitySimpleBinding.inflate(layoutInflater) + + override fun getCoordinatorLayout() = views.coordinatorLayout + + override fun initUiAndData() { + orientationLocker.lockPhonesToPortrait(this) + if (isFirstCreation()) { + addFragment(views.simpleFragmentContainer, ReleaseNotesFragment::class.java) + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesCarouselController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesCarouselController.kt new file mode 100644 index 0000000000..22d2915c47 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesCarouselController.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import com.airbnb.epoxy.TypedEpoxyController +import javax.inject.Inject + +class ReleaseNotesCarouselController @Inject constructor() : TypedEpoxyController() { + override fun buildModels(data: ReleaseCarouselData) { + data.items.forEachIndexed { index, item -> + releaseCarouselItem { + id(index) + item(item) + } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesFragment.kt new file mode 100644 index 0000000000..72cf875410 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesFragment.kt @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.viewpager2.widget.ViewPager2 +import com.airbnb.mvrx.fragmentViewModel +import com.google.android.material.tabs.TabLayoutMediator +import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.databinding.BottomSheetReleaseNotesBinding +import javax.inject.Inject + +@AndroidEntryPoint +class ReleaseNotesFragment : VectorBaseFragment() { + + @Inject lateinit var carouselController: ReleaseNotesCarouselController + private var tabLayoutMediator: TabLayoutMediator? = null + + private val viewModel by fragmentViewModel(ReleaseNotesViewModel::class) + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): BottomSheetReleaseNotesBinding { + return BottomSheetReleaseNotesBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val carouselAdapter = carouselController.adapter + views.releaseNotesCarousel.adapter = carouselAdapter + + tabLayoutMediator = TabLayoutMediator(views.releaseNotesCarouselIndicator, views.releaseNotesCarousel) { _, _ -> } + .also { it.attach() } + + views.releaseNotesCarousel.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + viewModel.handle(ReleaseNotesAction.PageSelected(position)) + updateButtonText(position) + } + }) + + carouselController.setData(createCarouselData()) + + views.releaseNotesBtnClose.onClick { close() } + views.releaseNotesButtonNext.onClick { + val isLastItemSelected = with(views.releaseNotesCarouselIndicator) { + selectedTabPosition == tabCount - 1 + } + viewModel.handle(ReleaseNotesAction.NextPressed(isLastItemSelected)) + } + + viewModel.observeViewEvents { + when (it) { + is ReleaseNotesViewEvents.SelectPage -> selectPage(it.index) + ReleaseNotesViewEvents.Close -> close() + } + } + } + + private fun createCarouselData(): ReleaseCarouselData { + return ReleaseCarouselData( + listOf( + ReleaseCarouselData.Item( + R.string.onboarding_new_app_layout_welcome_title, + R.string.onboarding_new_app_layout_welcome_message, + R.drawable.app_layout_onboarding_welcome + ), + ReleaseCarouselData.Item( + R.string.onboarding_new_app_layout_spaces_title, + R.string.onboarding_new_app_layout_spaces_message, + R.drawable.app_layout_onboarding_spaces + ), + ReleaseCarouselData.Item( + R.string.onboarding_new_app_layout_feedback_title, + R.string.onboarding_new_app_layout_feedback_message, + R.drawable.app_layout_onboarding_feedback + ), + ) + ) + } + + private fun close() { + requireActivity().onBackPressed() + } + + private fun selectPage(index: Int) { + views.releaseNotesCarouselIndicator.selectTab(views.releaseNotesCarouselIndicator.getTabAt(index)) + updateButtonText(index) + } + + private fun updateButtonText(selectedIndex: Int) { + val isLastItem = selectedIndex == views.releaseNotesCarouselIndicator.tabCount - 1 + if (isLastItem) { + views.releaseNotesButtonNext.setText(R.string.onboarding_new_app_layout_button_try) + } else { + views.releaseNotesButtonNext.setText(R.string.action_next) + } + } + + override fun onDestroyView() { + tabLayoutMediator?.detach() + tabLayoutMediator = null + + views.releaseNotesCarousel.adapter = null + super.onDestroyView() + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesPreferencesStore.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesPreferencesStore.kt new file mode 100644 index 0000000000..cefe107905 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesPreferencesStore.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.preferencesDataStore +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.map +import org.matrix.android.sdk.api.extensions.orFalse +import javax.inject.Inject + +private val Context.dataStore: DataStore by preferencesDataStore(name = "release_notes") + +class ReleaseNotesPreferencesStore @Inject constructor( + private val context: Context +) { + + private val isAppLayoutOnboardingShown = booleanPreferencesKey("SETTINGS_APP_LAYOUT_ONBOARDING_SHOWN") + + val appLayoutOnboardingShown: Flow = context.dataStore.data + .map { preferences -> preferences[isAppLayoutOnboardingShown].orFalse() } + .distinctUntilChanged() + + suspend fun setAppLayoutOnboardingShown(isShown: Boolean) { + context.dataStore.edit { settings -> + settings[isAppLayoutOnboardingShown] = isShown + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesViewEvents.kt new file mode 100644 index 0000000000..7901a8b28f --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesViewEvents.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import im.vector.app.core.platform.VectorViewEvents + +sealed class ReleaseNotesViewEvents : VectorViewEvents { + object Close : ReleaseNotesViewEvents() + data class SelectPage(val index: Int) : ReleaseNotesViewEvents() +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesViewModel.kt new file mode 100644 index 0000000000..7fa2d8659a --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/list/home/release/ReleaseNotesViewModel.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.list.home.release + +import com.airbnb.mvrx.MavericksViewModelFactory +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject +import im.vector.app.core.di.MavericksAssistedViewModelFactory +import im.vector.app.core.di.hiltMavericksViewModelFactory +import im.vector.app.core.platform.VectorDummyViewState +import im.vector.app.core.platform.VectorViewModel +import timber.log.Timber + +class ReleaseNotesViewModel @AssistedInject constructor( + @Assisted initialState: VectorDummyViewState, +) : VectorViewModel(initialState) { + + @AssistedFactory + interface Factory : MavericksAssistedViewModelFactory { + override fun create(initialState: VectorDummyViewState): ReleaseNotesViewModel + } + + companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory() + + private var selectedPageIndex = 0 + + init { + _viewEvents.post(ReleaseNotesViewEvents.SelectPage(selectedPageIndex)) + } + + override fun handle(action: ReleaseNotesAction) { + when (action) { + is ReleaseNotesAction.NextPressed -> handleNextPressed(action) + is ReleaseNotesAction.PageSelected -> handlePageSelected(action) + } + } + + private fun handlePageSelected(action: ReleaseNotesAction.PageSelected) { + Timber.d("carousel_index_v: ${action.selectedPageIndex}") + selectedPageIndex = action.selectedPageIndex + } + + private fun handleNextPressed(action: ReleaseNotesAction.NextPressed) { + if (action.isLastItemSelected) { + _viewEvents.post(ReleaseNotesViewEvents.Close) + } else { + Timber.d("carousel_index_v: ${selectedPageIndex + 1}") + _viewEvents.post(ReleaseNotesViewEvents.SelectPage(++selectedPageIndex)) + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt index 40ef6d819e..b1327f0caf 100644 --- a/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt +++ b/vector/src/main/java/im/vector/app/features/popup/PopupAlertManager.kt @@ -28,6 +28,7 @@ import im.vector.app.core.time.Clock import im.vector.app.core.utils.isAnimationEnabled import im.vector.app.features.MainActivity import im.vector.app.features.analytics.ui.consent.AnalyticsOptInActivity +import im.vector.app.features.home.room.list.home.release.ReleaseNotesActivity import im.vector.app.features.pin.PinActivity import im.vector.app.features.signout.hard.SignedOutActivity import im.vector.app.features.themes.ThemeUtils @@ -307,6 +308,7 @@ class PopupAlertManager @Inject constructor( activity !is PinActivity && activity !is SignedOutActivity && activity !is AnalyticsOptInActivity && + activity !is ReleaseNotesActivity && activity is VectorBaseActivity<*> && alert.shouldBeDisplayedIn.invoke(activity) } diff --git a/vector/src/main/res/drawable-hdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/drawable-hdpi/app_layout_onboarding_feedback.webp new file mode 100644 index 0000000000..5ac890e617 Binary files /dev/null and b/vector/src/main/res/drawable-hdpi/app_layout_onboarding_feedback.webp differ diff --git a/vector/src/main/res/drawable-hdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-hdpi/app_layout_onboarding_spaces.webp new file mode 100644 index 0000000000..35f2a04236 Binary files /dev/null and b/vector/src/main/res/drawable-hdpi/app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-hdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/drawable-hdpi/app_layout_onboarding_welcome.webp new file mode 100644 index 0000000000..5ac890e617 Binary files /dev/null and b/vector/src/main/res/drawable-hdpi/app_layout_onboarding_welcome.webp differ diff --git a/vector/src/main/res/drawable-mdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/drawable-mdpi/app_layout_onboarding_feedback.webp new file mode 100644 index 0000000000..07ece0d947 Binary files /dev/null and b/vector/src/main/res/drawable-mdpi/app_layout_onboarding_feedback.webp differ diff --git a/vector/src/main/res/drawable-mdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-mdpi/app_layout_onboarding_spaces.webp new file mode 100644 index 0000000000..a77bce20e8 Binary files /dev/null and b/vector/src/main/res/drawable-mdpi/app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-mdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/drawable-mdpi/app_layout_onboarding_welcome.webp new file mode 100644 index 0000000000..07ece0d947 Binary files /dev/null and b/vector/src/main/res/drawable-mdpi/app_layout_onboarding_welcome.webp differ diff --git a/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_feedback.webp new file mode 100644 index 0000000000..e86bd5fe6b Binary files /dev/null and b/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_feedback.webp differ diff --git a/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_spaces.webp new file mode 100644 index 0000000000..9b5b9fa607 Binary files /dev/null and b/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_welcome.webp new file mode 100644 index 0000000000..e86bd5fe6b Binary files /dev/null and b/vector/src/main/res/drawable-xhdpi/app_layout_onboarding_welcome.webp differ diff --git a/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_feedback.webp new file mode 100644 index 0000000000..f95909eaae Binary files /dev/null and b/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_feedback.webp differ diff --git a/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_spaces.webp new file mode 100644 index 0000000000..03e31dc9d6 Binary files /dev/null and b/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_welcome.webp new file mode 100644 index 0000000000..f95909eaae Binary files /dev/null and b/vector/src/main/res/drawable-xxhdpi/app_layout_onboarding_welcome.webp differ diff --git a/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_feedback.webp new file mode 100644 index 0000000000..cee3cf512c Binary files /dev/null and b/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_feedback.webp differ diff --git a/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_spaces.webp new file mode 100644 index 0000000000..b4bf421be5 Binary files /dev/null and b/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_spaces.webp differ diff --git a/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_welcome.webp new file mode 100644 index 0000000000..cee3cf512c Binary files /dev/null and b/vector/src/main/res/drawable-xxxhdpi/app_layout_onboarding_welcome.webp differ diff --git a/vector/src/main/res/layout/activity_home.xml b/vector/src/main/res/layout/activity_home.xml index 9899c15aa6..698aab2340 100644 --- a/vector/src/main/res/layout/activity_home.xml +++ b/vector/src/main/res/layout/activity_home.xml @@ -28,4 +28,4 @@ android:layout_height="match_parent" android:layout_gravity="start" /> - \ No newline at end of file + diff --git a/vector/src/main/res/layout/bottom_sheet_release_notes.xml b/vector/src/main/res/layout/bottom_sheet_release_notes.xml new file mode 100644 index 0000000000..09d60e49cb --- /dev/null +++ b/vector/src/main/res/layout/bottom_sheet_release_notes.xml @@ -0,0 +1,55 @@ + + + + + + + + + +