Commit 3b884eac authored by Marco Trevisan's avatar Marco Trevisan 🎺

calendar: Define EventSourceInterface and implement EventSource's

Objects implementing EventSource should have some mandatory methods and
properties, we can ensure this by defining an EventSourceInterface.

So inhert EmptyEventSource and DBusEventSource from GObject's making sure
that they implement the EventSourceInterface, using native properties and
replacing the 'notify::*' emissions with proper object notify calls.

GNOME/gnome-shell!563
parent 64657e1d
Pipeline #100282 passed with stages
in 9 minutes and 22 seconds
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported Calendar, CalendarMessageList */
/* exported Calendar, CalendarMessageList, DBusEventSource */
const { Clutter, Gio, GLib, Shell, St } = imports.gi;
const { Clutter, Gio, GLib, GObject, Shell, St } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main;
......@@ -99,17 +99,58 @@ var CalendarEvent = class CalendarEvent {
// Interface for appointments/events - e.g. the contents of a calendar
//
// First, an implementation with no events
var EmptyEventSource = class EmptyEventSource {
constructor() {
this.isLoading = false;
this.isDummy = true;
this.hasCalendars = false;
var EventSourceInterface = GObject.registerClass({
GTypeName: 'Calendar_EventSourceInterface',
Requires: [GObject.Object],
Properties: {
'has-calendars': GObject.ParamSpec.boolean('has-calendars',
'has-calendars',
'has-calendars',
GObject.ParamFlags.READABLE,
false)
},
Signals: { 'changed': {} }
}, class EventSourceInterface extends GObject.Interface {
get isLoading() {
throw new GObject.NotImplementedError(`isLoading in ${this.constructor.name}`);
}
get hasCalendars() {
throw new GObject.NotImplementedError(`hasCalendars in ${this.constructor.name}`);
}
destroy() {
}
requestRange(_begin, _end) {
throw new GObject.NotImplementedError(`requestRange in ${this.constructor.name}`);
}
getEvents(_begin, _end) {
throw new GObject.NotImplementedError(`getEvents in ${this.constructor.name}`);
}
hasEvents(_day) {
throw new GObject.NotImplementedError(`hasEvents in ${this.constructor.name}`);
}
});
var EmptyEventSource = GObject.registerClass({
GTypeName: 'Calendar_EmptyEventSource',
Implements: [EventSourceInterface],
Properties: {
'has-calendars': GObject.ParamSpec.override('has-calendars',
EventSourceInterface),
}
}, class EmptyEventSource extends GObject.Object {
get isLoading() {
return false;
}
get hasCalendars() {
return false;
}
requestRange(_begin, _end) {
}
......@@ -121,8 +162,7 @@ var EmptyEventSource = class EmptyEventSource {
hasEvents(_day) {
return false;
}
};
Signals.addSignalMethods(EmptyEventSource.prototype);
});
const CalendarServerIface = loadInterfaceXML('org.gnome.Shell.CalendarServer');
......@@ -154,11 +194,18 @@ function _dateIntervalsOverlap(a0, a1, b0, b1) {
}
// an implementation that reads data from a session bus service
var DBusEventSource = class DBusEventSource {
constructor() {
var DBusEventSource = GObject.registerClass({
GTypeName: 'Calendar_DBusEventSource',
Implements: [EventSourceInterface],
Properties: {
'has-calendars': GObject.ParamSpec.override('has-calendars',
EventSourceInterface),
}
}, class DBusEventSource extends GObject.Object {
_init() {
super._init();
this._resetCache();
this.isLoading = false;
this.isDummy = false;
this._isLoading = false;
this._initialized = false;
this._dbusProxy = new CalendarServer();
......@@ -193,12 +240,12 @@ var DBusEventSource = class DBusEventSource {
});
this._dbusProxy.connect('g-properties-changed', () => {
this.emit('notify::has-calendars');
this.notify('has-calendars');
});
this._initialized = loaded;
if (loaded) {
this.emit('notify::has-calendars');
this.notify('has-calendars');
this._onNameAppeared();
}
});
......@@ -215,6 +262,10 @@ var DBusEventSource = class DBusEventSource {
return false;
}
get isLoading() {
return this._isLoading;
}
_resetCache() {
this._events = [];
this._lastRequestBegin = null;
......@@ -252,7 +303,7 @@ var DBusEventSource = class DBusEventSource {
newEvents.sort((ev1, ev2) => ev1.date.getTime() - ev2.date.getTime());
this._events = newEvents;
this.isLoading = false;
this._isLoading = false;
this.emit('changed');
}
......@@ -272,7 +323,7 @@ var DBusEventSource = class DBusEventSource {
requestRange(begin, end) {
if (!(_datesEqual(begin, this._lastRequestBegin) && _datesEqual(end, this._lastRequestEnd))) {
this.isLoading = true;
this._isLoading = true;
this._lastRequestBegin = begin;
this._lastRequestEnd = end;
this._curRequestBegin = begin;
......@@ -310,8 +361,7 @@ var DBusEventSource = class DBusEventSource {
return true;
}
};
Signals.addSignalMethods(DBusEventSource.prototype);
});
var Calendar = class Calendar {
constructor() {
......@@ -354,9 +404,10 @@ var Calendar = class Calendar {
this._buildHeader ();
}
// @eventSource: is an object implementing the EventSource API, e.g. the
// requestRange(), getEvents(), hasEvents() methods and the ::changed signal.
setEventSource(eventSource) {
if (!(eventSource instanceof EventSourceInterface))
throw new Error('Event source is not valid type');
this._eventSource = eventSource;
this._eventSource.connect('changed', () => {
this._rebuildCalendar();
......@@ -559,7 +610,7 @@ var Calendar = class Calendar {
can_focus: true });
let rtl = button.get_text_direction() == Clutter.TextDirection.RTL;
if (this._eventSource.isDummy)
if (this._eventSource instanceof EmptyEventSource)
button.reactive = false;
button._date = new Date(iter);
......@@ -791,6 +842,9 @@ var EventsSection = class EventsSection extends MessageList.MessageListSection {
}
setEventSource(eventSource) {
if (!(eventSource instanceof EventSourceInterface))
throw new Error('Event source is not valid type');
this._eventSource = eventSource;
this._eventSource.connect('changed', this._reloadEvents.bind(this));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment