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$sUnverified · 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.050.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 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/layout/item_release_carousel.xml b/vector/src/main/res/layout/item_release_carousel.xml
new file mode 100644
index 0000000000..b2d7fea301
--- /dev/null
+++ b/vector/src/main/res/layout/item_release_carousel.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vector/src/main/res/res/drawable-hdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/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/res/drawable-hdpi/app_layout_onboarding_feedback.webp differ
diff --git a/vector/src/main/res/res/drawable-hdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/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/res/drawable-hdpi/app_layout_onboarding_spaces.webp differ
diff --git a/vector/src/main/res/res/drawable-hdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/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/res/drawable-hdpi/app_layout_onboarding_welcome.webp differ
diff --git a/vector/src/main/res/res/drawable-mdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/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/res/drawable-mdpi/app_layout_onboarding_feedback.webp differ
diff --git a/vector/src/main/res/res/drawable-mdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/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/res/drawable-mdpi/app_layout_onboarding_spaces.webp differ
diff --git a/vector/src/main/res/res/drawable-mdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/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/res/drawable-mdpi/app_layout_onboarding_welcome.webp differ
diff --git a/vector/src/main/res/res/drawable-xhdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/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/res/drawable-xhdpi/app_layout_onboarding_feedback.webp differ
diff --git a/vector/src/main/res/res/drawable-xhdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/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/res/drawable-xhdpi/app_layout_onboarding_spaces.webp differ
diff --git a/vector/src/main/res/res/drawable-xhdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/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/res/drawable-xhdpi/app_layout_onboarding_welcome.webp differ
diff --git a/vector/src/main/res/res/drawable-xxhdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/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/res/drawable-xxhdpi/app_layout_onboarding_feedback.webp differ
diff --git a/vector/src/main/res/res/drawable-xxhdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/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/res/drawable-xxhdpi/app_layout_onboarding_spaces.webp differ
diff --git a/vector/src/main/res/res/drawable-xxhdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/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/res/drawable-xxhdpi/app_layout_onboarding_welcome.webp differ
diff --git a/vector/src/main/res/res/drawable-xxxhdpi/app_layout_onboarding_feedback.webp b/vector/src/main/res/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/res/drawable-xxxhdpi/app_layout_onboarding_feedback.webp differ
diff --git a/vector/src/main/res/res/drawable-xxxhdpi/app_layout_onboarding_spaces.webp b/vector/src/main/res/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/res/drawable-xxxhdpi/app_layout_onboarding_spaces.webp differ
diff --git a/vector/src/main/res/res/drawable-xxxhdpi/app_layout_onboarding_welcome.webp b/vector/src/main/res/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/res/drawable-xxxhdpi/app_layout_onboarding_welcome.webp differ