diff --git a/scripts/langindex.json b/scripts/langindex.json
index b568c1a3c..ec7f4e8eb 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -2269,6 +2269,7 @@
"core.submit": "moodle",
"core.success": "moodle",
"core.summary": "moodle",
+ "core.swipenavigationtourdescription": "local_moodlemobileapp",
"core.tablet": "local_moodlemobileapp",
"core.tag.defautltagcoll": "tag",
"core.tag.errorareanotsupported": "local_moodlemobileapp",
diff --git a/src/assets/img/user-tours/swipe-navigation.svg b/src/assets/img/user-tours/swipe-navigation.svg
new file mode 100644
index 000000000..ac0c1732c
--- /dev/null
+++ b/src/assets/img/user-tours/swipe-navigation.svg
@@ -0,0 +1 @@
+
diff --git a/src/core/components/components.module.ts b/src/core/components/components.module.ts
index 0bfb96dc3..2ab8a0a30 100644
--- a/src/core/components/components.module.ts
+++ b/src/core/components/components.module.ts
@@ -60,6 +60,7 @@ import { CoreSpacerComponent } from './spacer/spacer';
import { CoreHorizontalScrollControlsComponent } from './horizontal-scroll-controls/horizontal-scroll-controls';
import { CoreButtonWithSpinnerComponent } from './button-with-spinner/button-with-spinner';
import { CoreSwipeSlidesComponent } from './swipe-slides/swipe-slides';
+import { CoreSwipeNavigationTourComponent } from './swipe-navigation-tour/swipe-navigation-tour';
@NgModule({
declarations: [
@@ -102,6 +103,7 @@ import { CoreSwipeSlidesComponent } from './swipe-slides/swipe-slides';
CoreComboboxComponent,
CoreSpacerComponent,
CoreHorizontalScrollControlsComponent,
+ CoreSwipeNavigationTourComponent,
],
imports: [
CommonModule,
@@ -151,6 +153,7 @@ import { CoreSwipeSlidesComponent } from './swipe-slides/swipe-slides';
CoreComboboxComponent,
CoreSpacerComponent,
CoreHorizontalScrollControlsComponent,
+ CoreSwipeNavigationTourComponent,
],
})
export class CoreComponentsModule {}
diff --git a/src/core/components/swipe-navigation-tour/core-swipe-navigation-tour.html b/src/core/components/swipe-navigation-tour/core-swipe-navigation-tour.html
new file mode 100644
index 000000000..e8b94a568
--- /dev/null
+++ b/src/core/components/swipe-navigation-tour/core-swipe-navigation-tour.html
@@ -0,0 +1,5 @@
+
+
{{ 'core.swipenavigationtourdescription' | translate }}
+
+ {{ 'core.endonesteptour' | translate }}
+
diff --git a/src/core/components/swipe-navigation-tour/swipe-navigation-tour.scss b/src/core/components/swipe-navigation-tour/swipe-navigation-tour.scss
new file mode 100644
index 000000000..f71e25d12
--- /dev/null
+++ b/src/core/components/swipe-navigation-tour/swipe-navigation-tour.scss
@@ -0,0 +1,12 @@
+:host {
+ max-width: 85vw;
+
+ img {
+ max-width: 300px;
+ }
+
+ p {
+ text-align: center;
+ }
+
+}
diff --git a/src/core/components/swipe-navigation-tour/swipe-navigation-tour.ts b/src/core/components/swipe-navigation-tour/swipe-navigation-tour.ts
new file mode 100644
index 000000000..fb5c59085
--- /dev/null
+++ b/src/core/components/swipe-navigation-tour/swipe-navigation-tour.ts
@@ -0,0 +1,35 @@
+// (C) Copyright 2015 Moodle Pty 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.
+
+import { Component } from '@angular/core';
+import { CoreUserTours } from '@features/usertours/services/user-tours';
+
+/**
+ * Component showing the User Tour for the Swipe Navigation feature.
+ */
+@Component({
+ selector: 'core-swipe-navigation-tour',
+ templateUrl: 'core-swipe-navigation-tour.html',
+ styleUrls: ['swipe-navigation-tour.scss'],
+})
+export class CoreSwipeNavigationTourComponent {
+
+ /**
+ * Dismiss User Tour.
+ */
+ async dismiss(): Promise {
+ await CoreUserTours.dismiss();
+ }
+
+}
diff --git a/src/core/directives/swipe-navigation.ts b/src/core/directives/swipe-navigation.ts
index a90ae68b9..081a7a85f 100644
--- a/src/core/directives/swipe-navigation.ts
+++ b/src/core/directives/swipe-navigation.ts
@@ -14,6 +14,8 @@
import { AfterViewInit, Directive, ElementRef, Input, OnDestroy } from '@angular/core';
import { CoreSwipeNavigationItemsManager } from '@classes/items-management/swipe-navigation-items-manager';
+import { CoreSwipeNavigationTourComponent } from '@components/swipe-navigation-tour/swipe-navigation-tour';
+import { CoreUserTours } from '@features/usertours/services/user-tours';
import { Gesture, GestureDetail } from '@ionic/angular';
import { CoreScreen } from '@services/screen';
import { GestureController, Platform } from '@singletons';
@@ -50,7 +52,8 @@ export class CoreSwipeNavigationDirective implements AfterViewInit, OnDestroy {
/**
* @inheritdoc
*/
- ngAfterViewInit(): void {
+ async ngAfterViewInit(): Promise {
+ // Set up gesture listener
const style = this.element.style;
this.swipeGesture = GestureController.create({
el: this.element,
@@ -71,6 +74,26 @@ export class CoreSwipeNavigationDirective implements AfterViewInit, OnDestroy {
},
});
this.swipeGesture.enable();
+
+ // Show user tour.
+ const source = this.manager?.getSource();
+
+ if (!source) {
+ return;
+ }
+
+ await source.waitForLoaded();
+
+ const items = source.getItems() ?? [];
+
+ if (items.length < 2) {
+ return;
+ }
+
+ await CoreUserTours.showIfPending({
+ id: 'swipe-navigation',
+ component: CoreSwipeNavigationTourComponent,
+ });
}
/**
diff --git a/src/core/lang.json b/src/core/lang.json
index 02ef670c7..8dd623b4e 100644
--- a/src/core/lang.json
+++ b/src/core/lang.json
@@ -302,6 +302,7 @@
"submit": "Submit",
"success": "Success",
"summary": "Summary",
+ "swipenavigationtourdescription": "Swipe left and right to navigate around.",
"tablet": "Tablet",
"teachers": "Teachers",
"thereisdatatosync": "There are offline {{$a}} to be synchronised.",