+
+
-
-
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/addon/calendar/pages/list/list.ts b/src/addon/calendar/pages/list/list.ts
index 355cb5b89..82c8b748f 100644
--- a/src/addon/calendar/pages/list/list.ts
+++ b/src/addon/calendar/pages/list/list.ts
@@ -25,6 +25,7 @@ import { CoreLocalNotificationsProvider } from '../../../../providers/local-noti
import { CoreCoursePickerMenuPopoverComponent } from '../../../../components/course-picker-menu/course-picker-menu-popover';
import { CoreEventsProvider } from '../../../../providers/events';
import { CoreAppProvider } from '../../../../providers/app';
+import { CoreSplitViewComponent } from '../../../../components/split-view/split-view';
/**
* Page that displays the list of calendar events.
@@ -36,6 +37,7 @@ import { CoreAppProvider } from '../../../../providers/app';
})
export class AddonCalendarListPage implements OnDestroy {
@ViewChild(Content) content: Content;
+ @ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent;
protected daysLoaded = 0;
protected emptyEventsTimes = 0; // Variable to identify consecutive calls returning 0 events.
@@ -56,7 +58,6 @@ export class AddonCalendarListPage implements OnDestroy {
events = [];
notificationsEnabled = false;
filteredEvents = [];
- eventToLoad = 1;
canLoadMore = false;
filter = {
course: this.allCourses
@@ -84,26 +85,15 @@ export class AddonCalendarListPage implements OnDestroy {
* View loaded.
*/
ionViewDidLoad() {
- if (this.eventId && !this.appProvider.isWide()) {
- // There is an event to load and it's a phone device, open the event in a new state.
+ if (this.eventId) {
+ // There is an event to load, open the event in a new state.
this.gotoEvent(this.eventId);
}
this.fetchData().then(() => {
- // @TODO: Split view once single event is done.
- if (this.eventId && this.appProvider.isWide()) {
- // There is an event to load and it's a tablet device. Search the position of the event in the list and load it.
- let found = this.events.findIndex((e) => {return e.id == this.eventId});
-
- if (found > 0) {
- this.eventToLoad = found + 1;
- } else {
- // Event not found in the list, open it in a new state. Use a $timeout to open the state after the
- // split view is loaded.
- //$timeout(function() {
- this.gotoEvent(this.eventId);
- //});
- }
+ if (!this.eventId && this.splitviewCtrl.isOn() && this.events.length > 0) {
+ // Take first and load it.
+ this.gotoEvent(this.events[0].id);
}
}).finally(() => {
this.eventsLoaded = true;
@@ -324,7 +314,8 @@ export class AddonCalendarListPage implements OnDestroy {
* Navigate to a particular event.
*/
gotoEvent(eventId) {
- this.navCtrl.push('AddonCalendarEventPage', {id: eventId});
+ this.eventId = eventId;
+ this.splitviewCtrl.push('AddonCalendarEventPage', {id: eventId});
}
/**
diff --git a/src/components/components.module.ts b/src/components/components.module.ts
index 6a37a8dae..0ce4dbc4d 100644
--- a/src/components/components.module.ts
+++ b/src/components/components.module.ts
@@ -21,6 +21,7 @@ import { CoreLoadingComponent } from './loading/loading';
import { CoreMarkRequiredComponent } from './mark-required/mark-required';
import { CoreInputErrorsComponent } from './input-errors/input-errors';
import { CoreShowPasswordComponent } from './show-password/show-password';
+import { CoreSplitViewComponent } from './split-view/split-view';
import { CoreIframeComponent } from './iframe/iframe';
import { CoreProgressBarComponent } from './progress-bar/progress-bar';
import { CoreEmptyBoxComponent } from './empty-box/empty-box';
@@ -40,6 +41,7 @@ import { CoreSitePickerComponent } from './site-picker/site-picker';
CoreMarkRequiredComponent,
CoreInputErrorsComponent,
CoreShowPasswordComponent,
+ CoreSplitViewComponent,
CoreIframeComponent,
CoreProgressBarComponent,
CoreEmptyBoxComponent,
@@ -68,6 +70,7 @@ import { CoreSitePickerComponent } from './site-picker/site-picker';
CoreMarkRequiredComponent,
CoreInputErrorsComponent,
CoreShowPasswordComponent,
+ CoreSplitViewComponent,
CoreIframeComponent,
CoreProgressBarComponent,
CoreEmptyBoxComponent,
diff --git a/src/components/split-view/placeholder/placeholder.html b/src/components/split-view/placeholder/placeholder.html
new file mode 100644
index 000000000..52e7e8bcc
--- /dev/null
+++ b/src/components/split-view/placeholder/placeholder.html
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/split-view/placeholder/placeholder.module.ts b/src/components/split-view/placeholder/placeholder.module.ts
new file mode 100644
index 000000000..d3133905f
--- /dev/null
+++ b/src/components/split-view/placeholder/placeholder.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { CoreSplitViewPlaceholderPage } from './placeholder';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '../../components.module';
+
+@NgModule({
+ declarations: [
+ CoreSplitViewPlaceholderPage,
+ ],
+ imports: [
+ CoreComponentsModule,
+ IonicPageModule.forChild(CoreSplitViewPlaceholderPage),
+ TranslateModule.forChild()
+ ],
+ exports: [
+ CoreSplitViewPlaceholderPage
+ ]
+})
+export class CorePlaceholderPageModule { }
diff --git a/src/components/split-view/placeholder/placeholder.scss b/src/components/split-view/placeholder/placeholder.scss
new file mode 100644
index 000000000..b854d8617
--- /dev/null
+++ b/src/components/split-view/placeholder/placeholder.scss
@@ -0,0 +1,3 @@
+core-placeholder {
+
+}
diff --git a/src/components/split-view/placeholder/placeholder.ts b/src/components/split-view/placeholder/placeholder.ts
new file mode 100644
index 000000000..da0c7cf36
--- /dev/null
+++ b/src/components/split-view/placeholder/placeholder.ts
@@ -0,0 +1,16 @@
+import { Component } from '@angular/core';
+import {
+ IonicPage,
+ NavController,
+ NavParams } from 'ionic-angular';
+
+@IonicPage()
+@Component({
+ selector: 'core-placeholder',
+ templateUrl: 'placeholder.html',
+})
+export class CoreSplitViewPlaceholderPage {
+
+ constructor(public navCtrl: NavController, public navParams: NavParams) { }
+
+}
diff --git a/src/components/split-view/split-view.html b/src/components/split-view/split-view.html
new file mode 100644
index 000000000..dbea8c69b
--- /dev/null
+++ b/src/components/split-view/split-view.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/components/split-view/split-view.scss b/src/components/split-view/split-view.scss
new file mode 100644
index 000000000..4383232eb
--- /dev/null
+++ b/src/components/split-view/split-view.scss
@@ -0,0 +1,39 @@
+core-split-view {
+ ion-menu.split-pane-side {
+ display: block;
+
+ .menu-inner {
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ -webkit-transform: initial;
+ transform: initial;
+ width: 100%;
+ }
+ }
+
+ .split-pane-main {
+ display: none;
+ }
+
+ .split-pane-visible {
+ .split-pane-main {
+ display: block;
+ }
+
+ .split-pane-side .core-split-item-selected {
+ background-color: $gray-lighter;
+ border-left: 5px solid $core-color-light;
+ &.item-md {
+ padding-left: $item-md-padding-start - 5px;
+ }
+ &.item-ios {
+ padding-left: $item-ios-padding-start - 5px;
+ }
+ &.item-wp {
+ padding-left: $item-wp-padding-start - 5px;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/components/split-view/split-view.ts b/src/components/split-view/split-view.ts
new file mode 100644
index 000000000..50295fbb1
--- /dev/null
+++ b/src/components/split-view/split-view.ts
@@ -0,0 +1,147 @@
+// (C) Copyright 2015 Martin Dougiamas
+//
+// 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.
+
+// Code based on https://github.com/martinpritchardelevate/ionic-split-pane-demo
+
+import { Component, ViewChild, Injectable, Input, ElementRef, OnInit } from '@angular/core';
+import { NavController, Nav } from 'ionic-angular';
+import { CoreSplitViewPlaceholderPage } from './placeholder/placeholder';
+
+/**
+ * Directive to create a split view layout.
+ *
+ * @description
+ * To init/change the right pane contents (content pane), inject this component in the master page.
+ * @ViewChild(CoreSplitViewComponent) splitviewCtrl: CoreSplitViewComponent;
+ * Then use the push function to load.
+ *
+ * Accepts the following params:
+ *
+ * @param {string|boolean} [when] When the split-pane should be shown. Can be a CSS media query expression, or a shortcut
+ * expression. Can also be a boolean expression. Check split-pane component documentation for more information.
+ *
+ * Example:
+ *
+ *
+ *
+ *
+ */
+@Component({
+ selector: 'core-split-view',
+ templateUrl: 'split-view.html'
+})
+export class CoreSplitViewComponent implements OnInit {
+ // @todo Mix both panels header buttons
+
+ @ViewChild('detailNav') _detailNav: Nav;
+ @Input() when?: string | boolean = "md"; //
+ protected _isOn: boolean = false;
+ protected masterPageName: string = "";
+ protected loadDetailPage: any = false;
+ protected element: HTMLElement; // Current element.
+
+ // Empty placeholder for the 'detail' page.
+ detailPage: any = null;
+
+ constructor(private _masterNav: NavController, element: ElementRef) {
+ this.element = element.nativeElement;
+ }
+
+ /**
+ * Component being initialized.
+ */
+ ngOnInit() {
+ // Get the master page name and set an empty page as a placeholder.
+ this.masterPageName = this._masterNav.getActive().component.name;
+ this.emptyDetails();
+ }
+
+ /**
+ * Check if both panels are shown. It depends on screen width.
+ *
+ * @return {boolean} If split view is enabled.
+ */
+ isOn(): boolean {
+ return this._isOn;
+ }
+
+ /**
+ * Push a page to the navigation stack. It will decide where to load it depending on the size of the screen.
+ *
+ * @param {any} page The component class or deeplink name you want to push onto the navigation stack.
+ * @param {any} params Any NavParams you want to pass along to the next view.
+ */
+ push(page: any, params?: any, element?: HTMLElement) {
+ if (this._isOn) {
+ this._detailNav.setRoot(page, params);
+ } else {
+ this.loadDetailPage = {
+ component: page,
+ data: params
+ };
+ this._masterNav.push(page, params);
+ }
+ }
+
+ /**
+ * Set the details panel to default info.
+ */
+ emptyDetails() {
+ this.loadDetailPage = false;
+ this._detailNav.setRoot('CoreSplitViewPlaceholderPage');
+ }
+
+ /**
+ * Splitpanel visibility has changed.
+ *
+ * @param {Boolean} isOn If it fits both panels at the same time.
+ */
+ onSplitPaneChanged(isOn) {
+ this._isOn = isOn;
+ if (this._masterNav && this._detailNav) {
+ (isOn) ? this.activateSplitView() : this.deactivateSplitView();
+ }
+ }
+
+ /**
+ * Enable the split view, show both panels and do some magical navigation.
+ */
+ activateSplitView() {
+ let currentView = this._masterNav.getActive(),
+ currentPageName = currentView.component.name;
+ if (currentPageName != this.masterPageName) {
+ // CurrentView is a 'Detail' page remove it from the 'master' nav stack.
+ this._masterNav.pop();
+
+ // and add it to the 'detail' nav stack.
+ this._detailNav.setRoot(currentView.component, currentView.data);
+ } else if (this.loadDetailPage) {
+ // MasterPage is shown, load the last detail page if found.
+ this._detailNav.setRoot(this.loadDetailPage.component, this.loadDetailPage.data);
+ }
+ this.loadDetailPage = false;
+ }
+
+ /**
+ * Disabled the split view, show only one panel and do some magical navigation.
+ */
+ deactivateSplitView() {
+ let detailView = this._detailNav.getActive(),
+ currentPageName = detailView.component.name;
+ if (currentPageName != 'CoreSplitViewPlaceholderPage') {
+ // Current detail view is a 'Detail' page so, not the placeholder page, push it on 'master' nav stack.
+ this._masterNav.push(detailView.component, detailView.data);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/providers/app.ts b/src/providers/app.ts
index d0cc6e579..7bc1f36be 100644
--- a/src/providers/app.ts
+++ b/src/providers/app.ts
@@ -200,16 +200,6 @@ export class CoreAppProvider {
return limited.indexOf(type) > -1;
}
- /**
- * Check if device is wide enough. It's used i.e. to show split view.
- *
- * @return {boolean} Whether the device uses a limited connection.
- */
- isWide() : boolean {
- //@todo Should use media querys like splitpane
- return this.platform.is('tablet');
- }
-
/**
* Check if the app is running in a Windows environment.
*