Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

311
gaia/apps/gallery/js/startup.js Executable file
View file

@ -0,0 +1,311 @@
/* global LazyLoader, Pick, Thumbnails, $, thumbnails */
/* global MediaDB, photodb, picking, setView, LAYOUT_MODE, currentView */
/* global Overlay, isPhone, doNotScanInBackgroundHack, fullscreenButtons */
/* global launchCameraApp, deleteSelectedItems, shareSelectedItems */
/* global resizeHandler, currentFrame, showFile, fileCreated, fileDeleted */
/* global files, thumbnailClickHandler, exitEdit */
(function startup() {
'use strict';
var firstScanDone = false; // Have we completed our first scan yet?
showUI(); // We're localized, so unhide
registerEventHandlers(); // Hook up UI elements
finishDBInitialization(); // Finish MediaDB initialization
setInitialView(); // Start off in thumbnail list mode
registerActivityHandler(); // Handle pick and browse activities
displayThumbnails(); // Get the thumbnails displayed
doNotScanInBackgroundHack(photodb); // Remove as part of bug 1046995
function showUI() {
// <body> children are hidden until the UI is translated
document.body.classList.remove('hidden');
// load frame_script.js for preview mode and show loading background
if (!isPhone) {
LazyLoader.load('js/frame_scripts.js');
}
// Tell performance monitors that our chrome is visible
window.performance.mark('navigationLoaded');
}
function registerEventHandlers() {
// Clicking on the select button goes to thumbnail select mode
$('thumbnails-select-button').onclick =
setView.bind(null, LAYOUT_MODE.select);
// Clicking on the cancel button goes from thumbnail select mode
// back to thumbnail list mode
$('selected-header').addEventListener('action',
setView.bind(null, LAYOUT_MODE.list));
if (!isPhone) {
$('fullscreen-toolbar-header').addEventListener('action', function() {
setView(LAYOUT_MODE.list);
});
}
// The camera buttons should launch the camera app
fullscreenButtons.camera.onclick = launchCameraApp;
$('thumbnails-camera-button').onclick = launchCameraApp;
Overlay.addEventListener('camera', launchCameraApp);
// Clicking on the delete button in thumbnail select mode deletes all
// selected items
$('thumbnails-delete-button').onclick = deleteSelectedItems;
// Clicking on the share button in select mode shares all selected images
$('thumbnails-share-button').onclick = shareSelectedItems;
Overlay.addEventListener('cancel', function() {
if (picking) {
Pick.cancel();
}
});
// Handle resize events
window.onresize = resizeHandler;
// All our buttons and UI elements are hooked up, so we've reached
// the "interactive" mark.
window.performance.mark('navigationInteractive');
}
// We created the MediaDB in thumbnails.js. Now we need to finish
// setting it up.
function finishDBInitialization() {
// Display a dialog if the DB needs to upgrade before becoming ready
photodb.onupgrading = function(evt) {
Overlay.show('upgrade');
};
// This is called when DeviceStorage becomes unavailable because the
// sd card is removed or because it is mounted for USB mass storage
// This may be called before onready if it is unavailable to begin with
// We don't need one of these handlers for the video db, since both
// will get the same event at more or less the same time.
photodb.onunavailable = function() {
// Switch back to the thumbnail view unless it is a pick activity.
// If we were viewing or editing an image it might not be there
// anymore when the MediaDB becomes available again.
if (!picking) {
// If we are editing image, call exitEdit to revoke blob URLs
// and close the editor object. This is a known case where the
// user can lose their work. See Bug 1148347
if (currentView === LAYOUT_MODE.edit) {
exitEdit();
}
setView(LAYOUT_MODE.list);
} else {
Pick.restart();
}
// If storage becomes unavailble (e.g. the user starts a USB Mass Storage
// Lock the user out of the app, and tell them why
var why = photodb.state;
if (why === MediaDB.NOCARD) {
Overlay.show('nocard');
}
else if (why === MediaDB.UNMOUNTED) {
Overlay.show('pluggedin');
}
};
photodb.onready = function() {
// Hide the nocard or pluggedin overlay if it is displayed
if (Overlay.current === 'nocard' || Overlay.current === 'pluggedin' ||
Overlay.current === 'upgrade') {
Overlay.hide();
}
// We also scan the file system for new files every time we get
// a ready event. That code is in a different event handler that
// is not registered until we are notified the Thumbnails.created
// promise resolves.
};
photodb.onscanstart = function onscanstart() {
// Prevents user to edit images when scanning pictures from storage
fullscreenButtons.edit.classList.add('disabled');
// Show the scanning indicator
$('throbber').classList.remove('hidden');
$('throbber').classList.add('throb');
};
photodb.onscanend = function onscanend() {
// Allows the user to edit images when scanning is finished
fullscreenButtons.edit.classList.remove('disabled');
if (Overlay.current === 'scanning') {
Overlay.show('emptygallery');
}
else if (!isPhone && !currentFrame.displayingImage &&
!currentFrame.displayingVideo) {
// focus on latest one if client hasn't clicked any of
// them
showFile(0);
}
// Hide the scanning indicator
// setTimeout() is to workaround Bug 1166500
$('throbber').classList.remove('throb');
setTimeout(function() { $('throbber').classList.add('hidden'); }, 100);
// If this was the first scan after startup, then tell
// performance monitors that the app is finally fully loaded and stable.
if (!firstScanDone) {
firstScanDone = true;
window.performance.mark('fullyLoaded');
}
};
// On devices with internal and external device storage, this handler is
// triggered when the user removes the sdcard. MediaDB remains usable
// and we'll get a bunch of deleted events for the files that are no longer
// available. But we need to listen to this event so we can switch back
// to the list of thumbnails. We don't want to be left viewing or editing
// a photo that is no longer available.
photodb.oncardremoved = function oncardremoved() {
// If the user pulls the sdcard while trying to pick an image, give up
if (picking) {
Pick.cancel();
return;
}
setView(LAYOUT_MODE.list);
};
// One or more files was created (or was just discovered by a scan)
photodb.oncreated = function(event) {
event.detail.forEach(fileCreated);
};
// One or more files were deleted (or were just discovered missing)
photodb.ondeleted = function(event) {
event.detail.forEach(fileDeleted);
};
// If the mediadb is not still in its initial OPENING state then we
// missed a "ready" or "unavailable" or "upgrading" event, and need
// to call the appropriate handler now. Note that we don't start scanning
// until after the ready event arrives and we enumerate the db, so it
// is not possible for us to miss a scanstart or scanend events. And if
// we miss a created or deleted event, the relevant files will be found
// during the enumeration, so this is all we have to look for now
switch (photodb.state) {
case MediaDB.UPGRADING:
photodb.onupgrading();
break;
case MediaDB.READY:
photodb.onready();
break;
case MediaDB.NOCARD:
case MediaDB.UNMOUNTED:
photodb.onunavailable();
break;
}
}
function setInitialView() {
// Start off in thumbnail list mode or in pick mode
if (picking) {
setView(LAYOUT_MODE.pick);
}
else {
setView(LAYOUT_MODE.list);
}
}
// Register a handler for pick and browse activities
function registerActivityHandler() {
navigator.mozSetMessageHandler('activity', function activityHandler(a) {
var activityName = a.source.name;
switch (activityName) {
case 'browse':
// The user is probably coming to us from the camera, and she probably
// wants to see the list of thumbnails. If the gallery was already
// running when the browse activity was started, then we might not be
// displaying the thumbnails. If we're currently displaying a single
// image, switch to the thumbnails. But if the user left the gallery
// in the middle of an edit or in the middle of making a selection,
// then returning to the thumbnail list would cause her to lose work,
// so in those cases we don't change anything and let the gallery
// resume where the user left it. See Bug 846220.
if (currentView === LAYOUT_MODE.fullscreen) {
setView(LAYOUT_MODE.list);
}
break;
case 'pick':
LazyLoader.load('js/pick.js', function() { Pick.start(a); });
break;
}
});
}
// Get the thumbnails displayed
function displayThumbnails() {
// thumbnails.js started created thumbanils offscreen.
// We're ready now to deal with them
// Copy stuff to global variables
// jshint ignore:start
thumbnails = Thumbnails.container; // The element that holds the thumbnail
thumbnailList = Thumbnails.list; // The object that represents them
// jshint ignore:end
// Now insert the thumbnails into the document.
var placeholder = $('thumbnails-placeholder');
placeholder.parentElement.replaceChild(thumbnails, placeholder);
// Handle clicks on the thumbnails
thumbnails.addEventListener('click', thumbnailClickHandler);
// When the first page of thumbnails is diplayed, we can emit
// our 'visually complete' mark for startup time comparison
Thumbnails.firstpage.then(function() {
// Tell performance monitors that "above the fold" content is displayed
// and is ready to interact with.
window.performance.mark('visuallyLoaded');
window.performance.mark('contentInteractive');
// Remove the attribute to trigger gaia header font-fit logic, defer it
// til now to postpone the overhead. Add setTimeout to lazyload
// gaia-header.js aynchronously.
setTimeout(function() {
LazyLoader.load(['shared/elements/gaia-header/dist/gaia-header.js'],
function() {
var headers = document.querySelectorAll('gaia-header');
for (var i = 0; i < headers.length; ++i) {
headers[i].removeAttribute('no-font-fit');
}
});
});
});
// When all the thumbnails have been created, we can start a scan
Thumbnails.complete.then(function() {
if (files.length === 0) { // If we didn't find anything
Overlay.show('scanning');
}
// Send a custom mark to performance monitors to note that we're done
// enumerating the database at this point. We won't send the final
// fullyLoaded marker until we're completely stable and have
// finished scanning.
window.performance.mark('mediaEnumerated');
// Now that we've enumerated all the photos and videos we already know
// about it is time to go and scan the filesystem for new ones. If the
// MediaDB is fully ready, we can scan now. Either way, we always want
// to scan every time we get a new 'ready' event.
photodb.addEventListener('ready', function() { photodb.scan(); });
if (photodb.state === MediaDB.READY) { // if already ready then scan now
photodb.scan();
}
});
}
})();