package org.activityinfo.ui.client.local.ui; /* * #%L * ActivityInfo Server * %% * Copyright (C) 2009 - 2013 UNICEF * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.MenuEvent; import com.extjs.gxt.ui.client.event.SelectionListener; import com.extjs.gxt.ui.client.widget.Status; import com.extjs.gxt.ui.client.widget.menu.Menu; import com.extjs.gxt.ui.client.widget.menu.MenuItem; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.RepeatingCommand; import com.google.gwt.user.client.Event; import com.google.inject.Inject; import org.activityinfo.i18n.shared.I18N; import org.activityinfo.ui.client.EventBus; import org.activityinfo.ui.client.local.sync.SyncCompleteEvent; import org.activityinfo.ui.client.local.sync.SyncRequestEvent; import java.util.Date; public class LastSyncStatus extends Status { private static final int UPDATE_DELAY = 30000; private static final int WARNING_THRESHOLD_SECONDS = 30 * 60; private final EventBus eventBus; private Date lastSyncTime; private Menu contextMenu; @Inject public LastSyncStatus(EventBus eventBus) { this.eventBus = eventBus; setStyleAttribute("cursor", "pointer"); eventBus.addListener(SyncCompleteEvent.TYPE, new Listener<SyncCompleteEvent>() { @Override public void handleEvent(SyncCompleteEvent event) { lastSyncTime = event.getTime(); setBox(true); updateLastSyncLabel(); } }); Scheduler.get().scheduleFixedPeriod(new RepeatingCommand() { @Override public boolean execute() { updateLastSyncLabel(); return true; } }, UPDATE_DELAY); sinkEvents(Event.ONCLICK); } public void createMenu() { MenuItem syncNow = new MenuItem(I18N.CONSTANTS.syncNow(), new SelectionListener<MenuEvent>() { @Override public void componentSelected(MenuEvent ce) { eventBus.fireEvent(SyncRequestEvent.INSTANCE); } }); this.contextMenu = new Menu(); contextMenu.add(syncNow); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); if (event.getTypeInt() == Event.ONCLICK) { if (contextMenu == null) { createMenu(); } contextMenu.show(getElement(), "bl-tl"); } } private void updateLastSyncLabel() { if (lastSyncTime != null) { setText(I18N.MESSAGES.lastSynced(formatLastSyncTime())); if (secondsSinceSync() > WARNING_THRESHOLD_SECONDS) { setIconStyle(SyncStatusResources.INSTANCE.style().warningIcon()); } else { setIconStyle(null); } } } private String formatLastSyncTime() { long secondsAgo = secondsSinceSync(); if (secondsAgo <= 60) { return I18N.CONSTANTS.relativeTimeMinAgo(); } long minutesAgo = secondsAgo / 60; if (minutesAgo <= 60) { return I18N.MESSAGES.minutesAgo((int) minutesAgo); } long hoursAgo = minutesAgo / 60; if (hoursAgo <= 48) { return I18N.MESSAGES.hoursAgo((int) hoursAgo); } long daysAgo = hoursAgo / 24; return I18N.MESSAGES.daysAgo((int) daysAgo); } private long secondsSinceSync() { long now = new Date().getTime(); long last = lastSyncTime.getTime(); long secondsAgo = (now - last) / 1000; return secondsAgo; } }