|
Packit Service |
ed5168 |
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
const { Clutter, GLib, GnomeDesktop,
|
|
Packit Service |
ed5168 |
GObject, GWeather, Shell, St } = imports.gi;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
const Util = imports.misc.util;
|
|
Packit Service |
ed5168 |
const Main = imports.ui.main;
|
|
Packit Service |
ed5168 |
const PanelMenu = imports.ui.panelMenu;
|
|
Packit Service |
ed5168 |
const Calendar = imports.ui.calendar;
|
|
Packit Service |
ed5168 |
const Weather = imports.misc.weather;
|
|
Packit Service |
ed5168 |
const System = imports.system;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
const MAX_FORECASTS = 5;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
function _isToday(date) {
|
|
Packit Service |
ed5168 |
let now = new Date();
|
|
Packit Service |
ed5168 |
return now.getYear() == date.getYear() &&
|
|
Packit Service |
ed5168 |
now.getMonth() == date.getMonth() &&
|
|
Packit Service |
ed5168 |
now.getDate() == date.getDate();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var TodayButton = class TodayButton {
|
|
Packit Service |
ed5168 |
constructor(calendar) {
|
|
Packit Service |
ed5168 |
// Having the ability to go to the current date if the user is already
|
|
Packit Service |
ed5168 |
// on the current date can be confusing. So don't make the button reactive
|
|
Packit Service |
ed5168 |
// until the selected date changes.
|
|
Packit Service |
ed5168 |
this.actor = new St.Button({ style_class: 'datemenu-today-button',
|
|
Packit Service |
ed5168 |
x_expand: true, x_align: St.Align.START,
|
|
Packit Service |
ed5168 |
can_focus: true,
|
|
Packit Service |
ed5168 |
reactive: false
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
this.actor.connect('clicked', () => {
|
|
Packit Service |
ed5168 |
this._calendar.setDate(new Date(), false);
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let hbox = new St.BoxLayout({ vertical: true });
|
|
Packit Service |
ed5168 |
this.actor.add_actor(hbox);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._dayLabel = new St.Label({ style_class: 'day-label',
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.START });
|
|
Packit Service |
ed5168 |
hbox.add_actor(this._dayLabel);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._dateLabel = new St.Label({ style_class: 'date-label' });
|
|
Packit Service |
ed5168 |
hbox.add_actor(this._dateLabel);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._calendar = calendar;
|
|
Packit Service |
ed5168 |
this._calendar.connect('selected-date-changed', (calendar, date) => {
|
|
Packit Service |
ed5168 |
// Make the button reactive only if the selected date is not the
|
|
Packit Service |
ed5168 |
// current date.
|
|
Packit Service |
ed5168 |
this.actor.reactive = !_isToday(date)
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
setDate(date) {
|
|
Packit Service |
ed5168 |
this._dayLabel.set_text(date.toLocaleFormat('%A'));
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
/* Translators: This is the date format to use when the calendar popup is
|
|
Packit Service |
ed5168 |
* shown - it is shown just below the time in the top bar (e.g.,
|
|
Packit Service |
ed5168 |
* "Tue 9:29 AM"). The string itself should become a full date, e.g.,
|
|
Packit Service |
ed5168 |
* "February 17 2015".
|
|
Packit Service |
ed5168 |
*/
|
|
Packit Service |
ed5168 |
let dateFormat = Shell.util_translate_time_string (N_("%B %-d %Y"));
|
|
Packit Service |
ed5168 |
this._dateLabel.set_text(date.toLocaleFormat(dateFormat));
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
/* Translators: This is the accessible name of the date button shown
|
|
Packit Service |
ed5168 |
* below the time in the shell; it should combine the weekday and the
|
|
Packit Service |
ed5168 |
* date, e.g. "Tuesday February 17 2015".
|
|
Packit Service |
ed5168 |
*/
|
|
Packit Service |
ed5168 |
dateFormat = Shell.util_translate_time_string (N_("%A %B %e %Y"));
|
|
Packit Service |
ed5168 |
this.actor.accessible_name = date.toLocaleFormat(dateFormat);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
};
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var WorldClocksSection = class WorldClocksSection {
|
|
Packit Service |
ed5168 |
constructor() {
|
|
Packit Service |
ed5168 |
this._clock = new GnomeDesktop.WallClock();
|
|
Packit Service |
ed5168 |
this._clockNotifyId = 0;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._locations = [];
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.actor = new St.Button({ style_class: 'world-clocks-button',
|
|
Packit Service |
ed5168 |
x_fill: true,
|
|
Packit Service |
ed5168 |
can_focus: true });
|
|
Packit Service |
ed5168 |
this.actor.connect('clicked', () => {
|
|
Packit Service |
ed5168 |
this._clockAppMon.activateApp();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
Main.overview.hide();
|
|
Packit Service |
ed5168 |
Main.panel.closeCalendar();
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
|
Packit Service |
ed5168 |
this._grid = new St.Widget({ style_class: 'world-clocks-grid',
|
|
Packit Service |
ed5168 |
layout_manager: layout });
|
|
Packit Service |
ed5168 |
layout.hookup_style(this._grid);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.actor.child = this._grid;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._clockAppMon = new Util.AppSettingsMonitor('org.gnome.clocks.desktop',
|
|
Packit Service |
ed5168 |
'org.gnome.clocks');
|
|
Packit Service |
ed5168 |
this._clockAppMon.connect('available-changed',
|
|
Packit Service |
ed5168 |
this._sync.bind(this));
|
|
Packit Service |
ed5168 |
this._clockAppMon.watchSetting('world-clocks',
|
|
Packit Service |
ed5168 |
this._clocksChanged.bind(this));
|
|
Packit Service |
ed5168 |
this._sync();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_sync() {
|
|
Packit Service |
ed5168 |
this.actor.visible = this._clockAppMon.available;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_clocksChanged(settings) {
|
|
Packit Service |
ed5168 |
this._grid.destroy_all_children();
|
|
Packit Service |
ed5168 |
this._locations = [];
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let world = GWeather.Location.get_world();
|
|
Packit Service |
ed5168 |
let clocks = settings.get_value('world-clocks').deep_unpack();
|
|
Packit Service |
ed5168 |
for (let i = 0; i < clocks.length; i++) {
|
|
Packit Service |
ed5168 |
if (!clocks[i].location)
|
|
Packit Service |
ed5168 |
continue;
|
|
Packit Service |
ed5168 |
let l = world.deserialize(clocks[i].location);
|
|
Packit Service |
ed5168 |
if (l && l.get_timezone() != null)
|
|
Packit Service |
ed5168 |
this._locations.push({ location: l });
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._locations.sort((a, b) => {
|
|
Packit Service |
ed5168 |
return a.location.get_timezone().get_offset() -
|
|
Packit Service |
ed5168 |
b.location.get_timezone().get_offset();
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let layout = this._grid.layout_manager;
|
|
Packit Service |
ed5168 |
let title = (this._locations.length == 0) ? _("Add world clocks…")
|
|
Packit Service |
ed5168 |
: _("World Clocks");
|
|
Packit Service |
ed5168 |
let header = new St.Label({ style_class: 'world-clocks-header',
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.START,
|
|
Packit Service |
ed5168 |
text: title });
|
|
Packit Service |
ed5168 |
layout.attach(header, 0, 0, 2, 1);
|
|
Packit Service |
ed5168 |
this.actor.label_actor = header;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let localOffset = GLib.DateTime.new_now_local().get_utc_offset();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
for (let i = 0; i < this._locations.length; i++) {
|
|
Packit Service |
ed5168 |
let l = this._locations[i].location;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let name = l.get_city_name() || l.get_name();
|
|
Packit Service |
ed5168 |
let label = new St.Label({ style_class: 'world-clocks-city',
|
|
Packit Service |
ed5168 |
text: name,
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.START,
|
|
Packit Service |
ed5168 |
y_align: Clutter.ActorAlign.CENTER,
|
|
Packit Service |
ed5168 |
x_expand: true });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let time = new St.Label({ style_class: 'world-clocks-time' });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let otherOffset = this._getTimeAtLocation(l).get_utc_offset();
|
|
Packit Service |
ed5168 |
let offset = (otherOffset - localOffset) / GLib.TIME_SPAN_HOUR;
|
|
Packit Service |
ed5168 |
let fmt = (Math.trunc(offset) == offset) ? '%s%.0f' : '%s%.1f';
|
|
Packit Service |
ed5168 |
let prefix = (offset >= 0) ? '+' : '-';
|
|
Packit Service |
ed5168 |
let tz = new St.Label({ style_class: 'world-clocks-timezone',
|
|
Packit Service |
ed5168 |
text: fmt.format(prefix, Math.abs(offset)),
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.END,
|
|
Packit Service |
ed5168 |
y_align: Clutter.ActorAlign.CENTER });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (this._grid.text_direction == Clutter.TextDirection.RTL) {
|
|
Packit Service |
ed5168 |
layout.attach(tz, 0, i + 1, 1, 1);
|
|
Packit Service |
ed5168 |
layout.attach(time, 1, i + 1, 1, 1);
|
|
Packit Service |
ed5168 |
layout.attach(label, 2, i + 1, 1, 1);
|
|
Packit Service |
ed5168 |
} else {
|
|
Packit Service |
ed5168 |
layout.attach(label, 0, i + 1, 1, 1);
|
|
Packit Service |
ed5168 |
layout.attach(time, 1, i + 1, 1, 1);
|
|
Packit Service |
ed5168 |
layout.attach(tz, 2, i + 1, 1, 1);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._locations[i].actor = time;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (this._grid.get_n_children() > 1) {
|
|
Packit Service |
ed5168 |
if (!this._clockNotifyId)
|
|
Packit Service |
ed5168 |
this._clockNotifyId =
|
|
Packit Service |
ed5168 |
this._clock.connect('notify::clock', this._updateLabels.bind(this));
|
|
Packit Service |
ed5168 |
this._updateLabels();
|
|
Packit Service |
ed5168 |
} else {
|
|
Packit Service |
ed5168 |
if (this._clockNotifyId)
|
|
Packit Service |
ed5168 |
this._clock.disconnect(this._clockNotifyId);
|
|
Packit Service |
ed5168 |
this._clockNotifyId = 0;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_getTimeAtLocation(location) {
|
|
Packit Service |
ed5168 |
let tz = GLib.TimeZone.new(location.get_timezone().get_tzid());
|
|
Packit Service |
ed5168 |
return GLib.DateTime.new_now(tz);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_updateLabels() {
|
|
Packit Service |
ed5168 |
for (let i = 0; i < this._locations.length; i++) {
|
|
Packit Service |
ed5168 |
let l = this._locations[i];
|
|
Packit Service |
ed5168 |
let now = this._getTimeAtLocation(l.location);
|
|
Packit Service |
ed5168 |
l.actor.text = Util.formatTime(now, { timeOnly: true });
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
};
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var WeatherSection = class WeatherSection {
|
|
Packit Service |
ed5168 |
constructor() {
|
|
Packit Service |
ed5168 |
this._weatherClient = new Weather.WeatherClient();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.actor = new St.Button({ style_class: 'weather-button',
|
|
Packit Service |
ed5168 |
x_fill: true,
|
|
Packit Service |
ed5168 |
can_focus: true });
|
|
Packit Service |
ed5168 |
this.actor.connect('clicked', () => {
|
|
Packit Service |
ed5168 |
this._weatherClient.activateApp();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
Main.overview.hide();
|
|
Packit Service |
ed5168 |
Main.panel.closeCalendar();
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
this.actor.connect('notify::mapped', () => {
|
|
Packit Service |
ed5168 |
if (this.actor.mapped)
|
|
Packit Service |
ed5168 |
this._weatherClient.update();
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let box = new St.BoxLayout({ style_class: 'weather-box',
|
|
Packit Service |
ed5168 |
vertical: true });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.actor.child = box;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let titleBox = new St.BoxLayout();
|
|
Packit Service |
ed5168 |
titleBox.add_child(new St.Label({ style_class: 'weather-header',
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.START,
|
|
Packit Service |
ed5168 |
x_expand: true,
|
|
Packit Service |
ed5168 |
text: _("Weather") }));
|
|
Packit Service |
ed5168 |
box.add_child(titleBox);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._titleLocation = new St.Label({ style_class: 'weather-header location',
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.END });
|
|
Packit Service |
ed5168 |
titleBox.add_child(this._titleLocation);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let layout = new Clutter.GridLayout({ orientation: Clutter.Orientation.VERTICAL });
|
|
Packit Service |
ed5168 |
this._forecastGrid = new St.Widget({ style_class: 'weather-grid',
|
|
Packit Service |
ed5168 |
layout_manager: layout });
|
|
Packit Service |
ed5168 |
layout.hookup_style(this._forecastGrid);
|
|
Packit Service |
ed5168 |
box.add_child(this._forecastGrid);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._weatherClient.connect('changed', this._sync.bind(this));
|
|
Packit Service |
ed5168 |
this._sync();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_getInfos() {
|
|
Packit Service |
ed5168 |
let info = this._weatherClient.info;
|
|
Packit Service |
ed5168 |
let forecasts = info.get_forecast_list();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let current = info;
|
|
Packit Service |
ed5168 |
let infos = [info];
|
|
Packit Service |
ed5168 |
for (let i = 0; i < forecasts.length; i++) {
|
|
Packit Service |
ed5168 |
let [ok, timestamp] = forecasts[i].get_value_update();
|
|
Packit Service |
ed5168 |
let datetime = new Date(timestamp * 1000);
|
|
Packit Service |
ed5168 |
if (!_isToday(datetime))
|
|
Packit Service |
ed5168 |
continue; // Ignore forecasts from other days
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
[ok, timestamp] = current.get_value_update();
|
|
Packit Service |
ed5168 |
let currenttime = new Date(timestamp * 1000);
|
|
Packit Service |
ed5168 |
if (currenttime.getHours() == datetime.getHours())
|
|
Packit Service |
ed5168 |
continue; // Enforce a minimum interval of 1h
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
current = forecasts[i];
|
|
Packit Service |
ed5168 |
if (infos.push(current) == MAX_FORECASTS)
|
|
Packit Service |
ed5168 |
break; // Use a maximum of five forecasts
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
return infos;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_addForecasts() {
|
|
Packit Service |
ed5168 |
let layout = this._forecastGrid.layout_manager;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let infos = this._getInfos();
|
|
Packit Service |
ed5168 |
if (this._forecastGrid.text_direction == Clutter.TextDirection.RTL)
|
|
Packit Service |
ed5168 |
infos.reverse();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let col = 0;
|
|
Packit Service |
ed5168 |
infos.forEach(fc => {
|
|
Packit Service |
ed5168 |
let [ok, timestamp] = fc.get_value_update();
|
|
Packit Service |
ed5168 |
let timeStr = Util.formatTime(new Date(timestamp * 1000), {
|
|
Packit Service |
ed5168 |
timeOnly: true
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let icon = new St.Icon({ style_class: 'weather-forecast-icon',
|
|
Packit Service |
ed5168 |
icon_name: fc.get_symbolic_icon_name(),
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.CENTER,
|
|
Packit Service |
ed5168 |
x_expand: true });
|
|
Packit Service |
ed5168 |
let temp = new St.Label({ style_class: 'weather-forecast-temp',
|
|
Packit Service |
ed5168 |
text: fc.get_temp_summary(),
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.CENTER });
|
|
Packit Service |
ed5168 |
let time = new St.Label({ style_class: 'weather-forecast-time',
|
|
Packit Service |
ed5168 |
text: timeStr,
|
|
Packit Service |
ed5168 |
x_align: Clutter.ActorAlign.CENTER });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
layout.attach(icon, col, 0, 1, 1);
|
|
Packit Service |
ed5168 |
layout.attach(temp, col, 1, 1, 1);
|
|
Packit Service |
ed5168 |
layout.attach(time, col, 2, 1, 1);
|
|
Packit Service |
ed5168 |
col++;
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_setStatusLabel(text) {
|
|
Packit Service |
ed5168 |
let layout = this._forecastGrid.layout_manager;
|
|
Packit Service |
ed5168 |
let label = new St.Label({ text });
|
|
Packit Service |
ed5168 |
layout.attach(label, 0, 0, 1, 1);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_updateForecasts() {
|
|
Packit Service |
ed5168 |
this._forecastGrid.destroy_all_children();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (!this._weatherClient.hasLocation) {
|
|
Packit Service |
ed5168 |
this._setStatusLabel(_("Select a location…"));
|
|
Packit Service |
ed5168 |
return;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let info = this._weatherClient.info;
|
|
Packit Service |
ed5168 |
this._titleLocation.text = info.get_location().get_name();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (this._weatherClient.loading) {
|
|
Packit Service |
ed5168 |
this._setStatusLabel(_("Loading…"));
|
|
Packit Service |
ed5168 |
return;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (info.is_valid()) {
|
|
Packit Service |
ed5168 |
this._addForecasts();
|
|
Packit Service |
ed5168 |
return;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (info.network_error())
|
|
Packit Service |
ed5168 |
this._setStatusLabel(_("Go online for weather information"));
|
|
Packit Service |
ed5168 |
else
|
|
Packit Service |
ed5168 |
this._setStatusLabel(_("Weather information is currently unavailable"));
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_sync() {
|
|
Packit Service |
ed5168 |
this.actor.visible = this._weatherClient.available;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
if (!this.actor.visible)
|
|
Packit Service |
ed5168 |
return;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._titleLocation.visible = this._weatherClient.hasLocation;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._updateForecasts();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
};
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var MessagesIndicator = class MessagesIndicator {
|
|
Packit Service |
ed5168 |
constructor() {
|
|
Packit Service |
ed5168 |
this.actor = new St.Icon({ icon_name: 'message-indicator-symbolic',
|
|
Packit Service |
ed5168 |
icon_size: 16,
|
|
Packit Service |
ed5168 |
visible: false, y_expand: true,
|
|
Packit Service |
ed5168 |
y_align: Clutter.ActorAlign.CENTER });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._sources = [];
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
Main.messageTray.connect('source-added', this._onSourceAdded.bind(this));
|
|
Packit Service |
ed5168 |
Main.messageTray.connect('source-removed', this._onSourceRemoved.bind(this));
|
|
Packit Service |
ed5168 |
Main.messageTray.connect('queue-changed', this._updateCount.bind(this));
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let sources = Main.messageTray.getSources();
|
|
Packit Service |
ed5168 |
sources.forEach(source => { this._onSourceAdded(null, source); });
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_onSourceAdded(tray, source) {
|
|
Packit Service |
ed5168 |
source.connect('count-updated', this._updateCount.bind(this));
|
|
Packit Service |
ed5168 |
this._sources.push(source);
|
|
Packit Service |
ed5168 |
this._updateCount();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_onSourceRemoved(tray, source) {
|
|
Packit Service |
ed5168 |
this._sources.splice(this._sources.indexOf(source), 1);
|
|
Packit Service |
ed5168 |
this._updateCount();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_updateCount() {
|
|
Packit Service |
ed5168 |
let count = 0;
|
|
Packit Service |
ed5168 |
this._sources.forEach(source => { count += source.unseenCount; });
|
|
Packit Service |
ed5168 |
count -= Main.messageTray.queueCount;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.actor.visible = (count > 0);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
};
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var IndicatorPad = GObject.registerClass(
|
|
Packit Service |
ed5168 |
class IndicatorPad extends St.Widget {
|
|
Packit Service |
ed5168 |
_init(actor) {
|
|
Packit Service |
ed5168 |
this._source = actor;
|
|
Packit Service |
ed5168 |
this._source.connect('notify::visible', () => { this.queue_relayout(); });
|
|
Packit Service |
ed5168 |
this._source.connect('notify::size', () => { this.queue_relayout(); });
|
|
Packit Service |
ed5168 |
super._init();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vfunc_get_preferred_width(forHeight) {
|
|
Packit Service |
ed5168 |
if (this._source.visible)
|
|
Packit Service |
ed5168 |
return this._source.get_preferred_width(forHeight);
|
|
Packit Service |
ed5168 |
return [0, 0];
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vfunc_get_preferred_height(forWidth) {
|
|
Packit Service |
ed5168 |
if (this._source.visible)
|
|
Packit Service |
ed5168 |
return this._source.get_preferred_height(forWidth);
|
|
Packit Service |
ed5168 |
return [0, 0];
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var FreezableBinLayout = GObject.registerClass(
|
|
Packit Service |
ed5168 |
class FreezableBinLayout extends Clutter.BinLayout {
|
|
Packit Service |
ed5168 |
_init() {
|
|
Packit Service |
ed5168 |
super._init();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._frozen = false;
|
|
Packit Service |
ed5168 |
this._savedWidth = [NaN, NaN];
|
|
Packit Service |
ed5168 |
this._savedHeight = [NaN, NaN];
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
set frozen(v) {
|
|
Packit Service |
ed5168 |
if (this._frozen == v)
|
|
Packit Service |
ed5168 |
return;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._frozen = v;
|
|
Packit Service |
ed5168 |
if (!this._frozen)
|
|
Packit Service |
ed5168 |
this.layout_changed();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vfunc_get_preferred_width(container, forHeight) {
|
|
Packit Service |
ed5168 |
if (!this._frozen || this._savedWidth.some(isNaN))
|
|
Packit Service |
ed5168 |
return super.vfunc_get_preferred_width(container, forHeight);
|
|
Packit Service |
ed5168 |
return this._savedWidth;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vfunc_get_preferred_height(container, forWidth) {
|
|
Packit Service |
ed5168 |
if (!this._frozen || this._savedHeight.some(isNaN))
|
|
Packit Service |
ed5168 |
return super.vfunc_get_preferred_height(container, forWidth);
|
|
Packit Service |
ed5168 |
return this._savedHeight;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vfunc_allocate(container, allocation, flags) {
|
|
Packit Service |
ed5168 |
super.vfunc_allocate(container, allocation, flags);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let [width, height] = allocation.get_size();
|
|
Packit Service |
ed5168 |
this._savedWidth = [width, width];
|
|
Packit Service |
ed5168 |
this._savedHeight = [height, height];
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var CalendarColumnLayout = GObject.registerClass(
|
|
Packit Service |
ed5168 |
class CalendarColumnLayout extends Clutter.BoxLayout {
|
|
Packit Service |
ed5168 |
_init(actor) {
|
|
Packit Service |
ed5168 |
super._init({ orientation: Clutter.Orientation.VERTICAL });
|
|
Packit Service |
ed5168 |
this._calActor = actor;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vfunc_get_preferred_width(container, forHeight) {
|
|
Packit Service |
ed5168 |
if (!this._calActor || this._calActor.get_parent() != container)
|
|
Packit Service |
ed5168 |
return super.vfunc_get_preferred_width(container, forHeight);
|
|
Packit Service |
ed5168 |
return this._calActor.get_preferred_width(forHeight);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
var DateMenuButton = GObject.registerClass(
|
|
Packit Service |
ed5168 |
class DateMenuButton extends PanelMenu.Button {
|
|
Packit Service |
ed5168 |
_init() {
|
|
Packit Service |
ed5168 |
let item;
|
|
Packit Service |
ed5168 |
let hbox;
|
|
Packit Service |
ed5168 |
let vbox;
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let menuAlignment = 0.5;
|
|
Packit Service |
ed5168 |
if (Clutter.get_default_text_direction() == Clutter.TextDirection.RTL)
|
|
Packit Service |
ed5168 |
menuAlignment = 1.0 - menuAlignment;
|
|
Packit Service |
ed5168 |
super._init(menuAlignment);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER });
|
|
Packit Service |
ed5168 |
this._indicator = new MessagesIndicator();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let box = new St.BoxLayout();
|
|
Packit Service |
ed5168 |
box.add_actor(new IndicatorPad(this._indicator.actor));
|
|
Packit Service |
ed5168 |
box.add_actor(this._clockDisplay);
|
|
Packit Service |
ed5168 |
box.add_actor(this._indicator.actor);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.actor.label_actor = this._clockDisplay;
|
|
Packit Service |
ed5168 |
this.actor.add_actor(box);
|
|
Packit Service |
ed5168 |
this.actor.add_style_class_name ('clock-display');
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let layout = new FreezableBinLayout();
|
|
Packit Service |
ed5168 |
let bin = new St.Widget({ layout_manager: layout });
|
|
Packit Service |
ed5168 |
// For some minimal compatibility with PopupMenuItem
|
|
Packit Service |
ed5168 |
bin._delegate = this;
|
|
Packit Service |
ed5168 |
this.menu.box.add_child(bin);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
hbox = new St.BoxLayout({ name: 'calendarArea' });
|
|
Packit Service |
ed5168 |
bin.add_actor(hbox);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._calendar = new Calendar.Calendar();
|
|
Packit Service |
ed5168 |
this._calendar.connect('selected-date-changed',
|
|
Packit Service |
ed5168 |
(calendar, date) => {
|
|
Packit Service |
ed5168 |
layout.frozen = !_isToday(date);
|
|
Packit Service |
ed5168 |
this._messageList.setDate(date);
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this.menu.connect('open-state-changed', (menu, isOpen) => {
|
|
Packit Service |
ed5168 |
// Whenever the menu is opened, select today
|
|
Packit Service |
ed5168 |
if (isOpen) {
|
|
Packit Service |
ed5168 |
let now = new Date();
|
|
Packit Service |
ed5168 |
this._calendar.setDate(now);
|
|
Packit Service |
ed5168 |
this._date.setDate(now);
|
|
Packit Service |
ed5168 |
this._messageList.setDate(now);
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
});
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
// Fill up the first column
|
|
Packit Service |
ed5168 |
this._messageList = new Calendar.CalendarMessageList();
|
|
Packit Service |
ed5168 |
hbox.add(this._messageList.actor, { expand: true, y_fill: false, y_align: St.Align.START });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
// Fill up the second column
|
|
Packit Service |
ed5168 |
let boxLayout = new CalendarColumnLayout(this._calendar.actor);
|
|
Packit Service |
ed5168 |
vbox = new St.Widget({ style_class: 'datemenu-calendar-column',
|
|
Packit Service |
ed5168 |
layout_manager: boxLayout });
|
|
Packit Service |
ed5168 |
boxLayout.hookup_style(vbox);
|
|
Packit Service |
ed5168 |
hbox.add(vbox);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._date = new TodayButton(this._calendar);
|
|
Packit Service |
ed5168 |
vbox.add_actor(this._date.actor);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
vbox.add_actor(this._calendar.actor);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._displaysSection = new St.ScrollView({ style_class: 'datemenu-displays-section vfade',
|
|
Packit Service |
ed5168 |
x_expand: true, x_fill: true,
|
|
Packit Service |
ed5168 |
overlay_scrollbars: true });
|
|
Packit Service |
ed5168 |
this._displaysSection.set_policy(St.PolicyType.NEVER, St.PolicyType.AUTOMATIC);
|
|
Packit Service |
ed5168 |
vbox.add_actor(this._displaysSection);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
let displaysBox = new St.BoxLayout({ vertical: true,
|
|
Packit Service |
ed5168 |
style_class: 'datemenu-displays-box' });
|
|
Packit Service |
ed5168 |
this._displaysSection.add_actor(displaysBox);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._clocksItem = new WorldClocksSection();
|
|
Packit Service |
ed5168 |
displaysBox.add(this._clocksItem.actor, { x_fill: true });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._weatherItem = new WeatherSection();
|
|
Packit Service |
ed5168 |
displaysBox.add(this._weatherItem.actor, { x_fill: true });
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
// Done with hbox for calendar and event list
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._clock = new GnomeDesktop.WallClock();
|
|
Packit Service |
ed5168 |
this._clock.bind_property('clock', this._clockDisplay, 'text', GObject.BindingFlags.SYNC_CREATE);
|
|
Packit Service |
ed5168 |
this._clock.connect('notify::timezone', this._updateTimeZone.bind(this));
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
|
Packit Service |
ed5168 |
this._sessionUpdated();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_getEventSource() {
|
|
Packit Service |
ed5168 |
return new Calendar.DBusEventSource();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_setEventSource(eventSource) {
|
|
Packit Service |
ed5168 |
if (this._eventSource)
|
|
Packit Service |
ed5168 |
this._eventSource.destroy();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._calendar.setEventSource(eventSource);
|
|
Packit Service |
ed5168 |
this._messageList.setEventSource(eventSource);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._eventSource = eventSource;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_updateTimeZone() {
|
|
Packit Service |
ed5168 |
// SpiderMonkey caches the time zone so we must explicitly clear it
|
|
Packit Service |
ed5168 |
// before we can update the calendar, see
|
|
Packit Service |
ed5168 |
// https://bugzilla.gnome.org/show_bug.cgi?id=678507
|
|
Packit Service |
ed5168 |
System.clearDateCaches();
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
this._calendar.updateTimeZone();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
_sessionUpdated() {
|
|
Packit Service |
ed5168 |
let eventSource;
|
|
Packit Service |
ed5168 |
let showEvents = Main.sessionMode.showCalendarEvents;
|
|
Packit Service |
ed5168 |
if (showEvents) {
|
|
Packit Service |
ed5168 |
eventSource = this._getEventSource();
|
|
Packit Service |
ed5168 |
} else {
|
|
Packit Service |
ed5168 |
eventSource = new Calendar.EmptyEventSource();
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
this._setEventSource(eventSource);
|
|
Packit Service |
ed5168 |
|
|
Packit Service |
ed5168 |
// Displays are not actually expected to launch Settings when activated
|
|
Packit Service |
ed5168 |
// but the corresponding app (clocks, weather); however we can consider
|
|
Packit Service |
ed5168 |
// that display-specific settings, so re-use "allowSettings" here ...
|
|
Packit Service |
ed5168 |
this._displaysSection.visible = Main.sessionMode.allowSettings;
|
|
Packit Service |
ed5168 |
}
|
|
Packit Service |
ed5168 |
});
|