mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-30 15:52:10 +02:00
227 lines
5.4 KiB
JavaScript
227 lines
5.4 KiB
JavaScript
const { Gio, GLib, Gdk, Gtk } = imports.gi;
|
||
const Debug = imports.src.debug;
|
||
|
||
const { debug } = Debug;
|
||
|
||
var appName = 'Clapper';
|
||
var appId = 'com.github.rafostar.Clapper';
|
||
var subsMimes = [
|
||
'application/x-subrip',
|
||
'text/x-ssa',
|
||
];
|
||
|
||
var settings = new Gio.Settings({
|
||
schema_id: appId,
|
||
});
|
||
|
||
var maxVolume = 1.5;
|
||
|
||
/* Keys must be lowercase */
|
||
const subsTitles = {
|
||
sdh: 'SDH',
|
||
cc: 'CC',
|
||
traditional: 'Traditional',
|
||
simplified: 'Simplified',
|
||
honorifics: 'Honorifics',
|
||
};
|
||
const subsKeys = Object.keys(subsTitles);
|
||
|
||
let inhibitCookie;
|
||
|
||
function getResourceUri(path)
|
||
{
|
||
const res = `file://${pkg.pkgdatadir}/${path}`;
|
||
|
||
debug(`importing ${res}`);
|
||
|
||
return res;
|
||
}
|
||
|
||
function getBuilderForName(name)
|
||
{
|
||
return Gtk.Builder.new_from_file(`${pkg.pkgdatadir}/ui/${name}`);
|
||
}
|
||
|
||
function loadCustomCss()
|
||
{
|
||
const cssProvider = new Gtk.CssProvider();
|
||
|
||
cssProvider.load_from_path(`${pkg.pkgdatadir}/css/styles.css`);
|
||
|
||
Gtk.StyleContext.add_provider_for_display(
|
||
Gdk.Display.get_default(),
|
||
cssProvider,
|
||
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
|
||
);
|
||
}
|
||
|
||
function getClapperThemeIconUri()
|
||
{
|
||
const display = Gdk.Display.get_default();
|
||
if(!display) return null;
|
||
|
||
const iconTheme = Gtk.IconTheme.get_for_display(display);
|
||
if(!iconTheme || !iconTheme.has_icon(appId))
|
||
return null;
|
||
|
||
const iconPaintable = iconTheme.lookup_icon(appId, null, 256, 1,
|
||
Gtk.TextDirection.NONE, Gtk.IconLookupFlags.FORCE_REGULAR
|
||
);
|
||
const iconFile = iconPaintable.get_file();
|
||
if(!iconFile) return null;
|
||
|
||
const iconPath = iconFile.get_path();
|
||
if(!iconPath) return null;
|
||
|
||
let substractName = iconPath.substring(
|
||
iconPath.indexOf('/icons/') + 7, iconPath.indexOf('/scalable/')
|
||
);
|
||
if(!substractName || substractName.includes('/'))
|
||
return null;
|
||
|
||
substractName = substractName.toLowerCase();
|
||
const postFix = (substractName === iconTheme.theme_name.toLowerCase())
|
||
? substractName
|
||
: 'hicolor';
|
||
const cacheIconName = `clapper-${postFix}.svg`;
|
||
|
||
/* We need to have this icon placed in a folder
|
||
* accessible from both app runtime and gnome-shell */
|
||
const expectedFile = Gio.File.new_for_path(
|
||
GLib.get_user_cache_dir() + `/${appId}/icons/${cacheIconName}`
|
||
);
|
||
if(!expectedFile.query_exists(null)) {
|
||
debug('no cached icon file');
|
||
|
||
const dirPath = expectedFile.get_parent().get_path();
|
||
GLib.mkdir_with_parents(dirPath, 493); // octal 755
|
||
iconFile.copy(expectedFile,
|
||
Gio.FileCopyFlags.TARGET_DEFAULT_PERMS, null, null
|
||
);
|
||
debug(`icon copied to cache dir: ${cacheIconName}`);
|
||
}
|
||
const iconUri = expectedFile.get_uri();
|
||
debug(`using cached clapper icon uri: ${iconUri}`);
|
||
|
||
return iconUri;
|
||
}
|
||
|
||
function getSubsTitle(infoTitle)
|
||
{
|
||
if(!infoTitle)
|
||
return null;
|
||
|
||
const searchName = infoTitle.toLowerCase();
|
||
const found = subsKeys.find(key => key === searchName);
|
||
|
||
return (found) ? subsTitles[found] : null;
|
||
}
|
||
|
||
function setAppInhibit(isInhibit, window)
|
||
{
|
||
let isInhibited = false;
|
||
|
||
if(isInhibit) {
|
||
if(inhibitCookie)
|
||
return;
|
||
|
||
const app = window.get_application();
|
||
|
||
inhibitCookie = app.inhibit(
|
||
window,
|
||
Gtk.ApplicationInhibitFlags.IDLE,
|
||
'video is playing'
|
||
);
|
||
if(!inhibitCookie)
|
||
debug(new Error('could not inhibit session!'));
|
||
|
||
isInhibited = (inhibitCookie > 0);
|
||
}
|
||
else {
|
||
if(!inhibitCookie)
|
||
return;
|
||
|
||
const app = window.get_application();
|
||
app.uninhibit(inhibitCookie);
|
||
inhibitCookie = null;
|
||
}
|
||
|
||
debug(`set prevent suspend to: ${isInhibited}`);
|
||
}
|
||
|
||
function getFormattedTime(time, showHours)
|
||
{
|
||
let hours;
|
||
|
||
if(showHours || time >= 3600) {
|
||
hours = ('0' + Math.floor(time / 3600)).slice(-2);
|
||
time -= hours * 3600;
|
||
}
|
||
const minutes = ('0' + Math.floor(time / 60)).slice(-2);
|
||
time -= minutes * 60;
|
||
const seconds = ('0' + Math.floor(time)).slice(-2);
|
||
|
||
const parsed = (hours) ? `${hours}∶` : '';
|
||
return parsed + `${minutes}∶${seconds}`;
|
||
}
|
||
|
||
function parsePlaylistFiles(filesArray)
|
||
{
|
||
let index = filesArray.length;
|
||
let subs = null;
|
||
|
||
while(index--) {
|
||
const file = filesArray[index];
|
||
const filename = (file.get_basename)
|
||
? file.get_basename()
|
||
: file.substring(file.lastIndexOf('/') + 1);
|
||
|
||
const [type, isUncertain] = Gio.content_type_guess(filename, null);
|
||
|
||
if(subsMimes.includes(type)) {
|
||
subs = file;
|
||
filesArray.splice(index, 1);
|
||
}
|
||
}
|
||
|
||
/* We only support single video
|
||
* with external subtitles */
|
||
if(subs && filesArray.length > 1)
|
||
subs = null;
|
||
|
||
return [filesArray, subs];
|
||
}
|
||
|
||
function getFileFromLocalUri(uri)
|
||
{
|
||
const file = Gio.file_new_for_uri(uri);
|
||
|
||
if(!file.query_exists(null)) {
|
||
debug(new Error(`file does not exist: ${file.get_path()}`));
|
||
|
||
return null;
|
||
}
|
||
|
||
return file;
|
||
}
|
||
|
||
/* JS replacement of "Gst.Uri.get_protocol" */
|
||
function getUriProtocol(uri)
|
||
{
|
||
const arr = uri.split(':');
|
||
return (arr.length > 1) ? arr[0] : null;
|
||
}
|
||
|
||
function getIsTouch(gesture)
|
||
{
|
||
const { source } = gesture.get_device();
|
||
|
||
switch(source) {
|
||
case Gdk.InputSource.PEN:
|
||
case Gdk.InputSource.TOUCHSCREEN:
|
||
return true;
|
||
default:
|
||
return false;
|
||
}
|
||
}
|