Set Notification Icon in Gnome Shell >= 3.16 (Custom Extension) - javascript

I've forked a Gnome Shell Extension, as I want to modify it to fit my personal preferences. I want to send a notification each time an event occurs. Sending the notification itself is fairly easy with Main.notify(summary, text). However, I just can't find out how to set a custom icon. [EDIT: The following is wrong. I looked up bad code]According to the github repo of gnome-shell I can define an icon via an optional parameter: Main.notify(summary, text, params), where params will be checked in MessageTray.js l.367:
params = Params.parse(params, { gicon: null,
secondaryGIcon: null,
bannerMarkup: false,
clear: false,
soundName: null,
soundFile: null });
if (params.gicon || params.clear)
this.gicon = params.gicon;
So I tried to use the following command:
Main.notify(summary, text, {gicon: myicon});
But the {gicon: myicon} part is ignored completely and the default icon is used :-/.
I'm new to Javascript and GNOME programming, so pls don't hate me :-)
Is using Main.notify() recommended generally, or is it deprecated?
Cheers, Maphardam

I think that Main.notify() is generally recommended, as it is used in some of the "official" extensions.
However, Main.notify() only takes two parameters (msg, details) and thus you cannot use this function to set a custom icon.
You can however copy the source of Main.notify() and adapt it to your own needs. Inside the following function the source of the notification is set to a newly created source with a custom icon.
function notify(msg, details, icon) {
let source = new MessageTray.Source("MyApp Information", icon);
Main.messageTray.add(source);
let notification = new MessageTray.Notification(source, msg, details);
notification.setTransient(true);
source.notify(notification);
}
For example you could call it with notify("MyApp", "Test", 'folder-symbolic');.

Related

Open a CEP dialog from a CEP extension in After Effects

I have a CEP extension in After Effects and I want it so that when a user clicks a button, a settings dialog opens up in a new floating dialog box. Seems like it would be such basic functionality but somehow I'm not seeing anywhere in the (admittedly sparse) documentation how to open up a dialog box. I've seen some other people say that you can make a hidden extension which opens the dialog, but I've seen no example of that and it is unclear how that would work to me.
You can look up documentation for ScriptUI. Heres a link to the pdf: https://adobeindd.com/view/publications/a0207571-ff5b-4bbf-a540-07079bd21d75/92ra/publication-web-resources/pdf/scriptui-2-16-j.pdf
You can create a dialog either in a function in the jsx, or give it its own jsx page and //#include it onclick.
I know this is kind of a generic answer, but incase anyone else is having trouble this will give you a good jumping off point.
So in order to provide the functionality you need, you'll have to initialize a dialog box first, then add a button, then force it to open a specific settings dialog. I recommend something like this:
var dialog = new Window("dialog");
dialog.text = "After Effects Dialog Script";
//Contents
var newMsg = dialog.add("group", undefined, {name: "newMsg"});
newMsg.orientation = "column";
var newMsgText = newMsg.add("statictext", [0, 0, 400, 40], "", {name: "newMsgText", multiline: true});
newMsgText.text = "Would you like to open a settings dialog?";
//Button UI
var buttonPanel = dialog.add("group", undefined, {name: "buttonPanel"});
buttonPanel.orientation = "row";
buttonPanel.alignChildren = ["center", "bottom"];
var enter = buttonPanel.add("button", undefined, undefined, {name: "ok"});
enter.text = "Continue";
enter.value = true;
var cancel = buttonPanel.add("button", undefined, undefined, {name: "cancel"});
cancel.text = "Cancel";
cancel.value = false;
//Runs the dialog code
dialog.show();
//Grabs answer to yes or no question
var dialogInput = dialog.show();
if(dialogInput == true){
app.openDlg (prompt, filter, multiSelect); //Essentially
}
else {
alert("The action was canceled.");
}
You will have to find the direct path to the CEP dialog you wish to open. I'm unfamiliar with them and their integrations to After Effects, so I can't help you much beyond getting the script set up. However I have a few comments on resources that may be of assistance here too.
That ScriptUI resource by Peter Kahrel is fantastic. I've been working with it for the last few weeks. I wanted to add on to what Jake L said by dropping in a few more great examples of Extendscript Support because you kinda have to dig for the documentation, but it's definitely there.
https://extendscript.docsforadobe.dev/
I just stumbled upon the Extendscript Library recently, but it details a lot of functions, dives deep into events and event handlers, and even explains how you can set up an environment for extendscript via vscode.
I also like to check out NTProductions on youtube for assistance. I'm working in Indesign, but a lot of the extendscript functions work between the various adobe programs and you can even troubleshoot basic functions in the Adobe ExtendScript Toolkit.
And if you already have an Adobe CC account, don't forget to download the Scripting SDK from adobe APIs and Services. You'll have to sign in to get there, but it's a pretty useful local documentation.
https://developer.adobe.com/console/servicesandapis/id#
EDIT (again): I also found these after posting and will commit to adding more as I find them. Extendscript documentation must become more available! :-)
https://docsforadobe.dev/
http://yearbook.github.io/esdocs/#/

Adding sound(s) on mouse click

I'm creating a helper GNOME extension for my theme. The helper extension was meant to be used to add some sounds when I click a button, however, I can't find a solution (and an extension) that shows how to add the sounds and how to call them.
Actually, I found some questions and articles that explains how to add an audio function, but most of it requires HTML.
I've tried using this code (through the Looking Glass and the extension.js file) from here, which says that it doesn't require HTML things:
function playSound() {
var audio = new Audio('/path/to/audio/file');
audio.play();
}
However, it returned unknown function error for Audio():
ReferenceError: Audio is not defined
Can someone help me? Thanks!
If you are using GNOME Shell >= 3.32 you can use MetaSoundPlayer:
const Gio = imports.gi.Gio;
let player = global.display.get_sound_player();
// Themed sound
player.play_from_theme('phone-incoming-call', 'arbitrary description', null);
// Sound File
let soundFile = Gio.File.new_for_path('/some/path/sound.ogg');
player.play_from_file(soundFile, 'arbitrary description', null);
Or there are global functions in GNOME Shell <= 3.30 (old docs):
// Themed sound
global.play_theme_sound(0, 'phone-incoming-call', 'arbitrary description', null);
// File name
global.play_sound_file(0, '/some/path/sound.ogg', 'arbitrary description', null);
There is a gnome-shell commit showing examples of both here.

How to add custom header for accessing a page URL and then performing test automation on that page, i am using a webdriverio,mocha,nodejs framework

I have a web page where the functionality changes when a custom header "headerKey": "headervalue" is being set through a chrome extension. While I can do this manually I want to do it through the code in order to do test automation.
Note:-
Please help with the approaches.
There is no functionality in webdriver to perform this operation.
I have used modheader but it is not working.
getModHeaderExtension() {
const filename = path.join(__dirname, "Modify.crx");
console.log(filename);
const stream = fs.readFileSync(filename);
return new Buffer(stream).toString('base64');
}
I know some time passed since the question was added, although it took me some time to figure it out by myself so maybe someone will make use of it.
Add #wdio/devtools-service to your dev dependencies (this should have the same major version as your other #wdio libraries, otherwise you can get some problems)
You need to add devtools to services in wdio.conf.ts:
export const config = {
[...]
services: ['chromedriver', 'devtools']
[...]
}
Now add you can add headers in you test method or wherever you need to:
const encodedCredentials = base64.encode(`${appConfig.basicAuthDevUser.userName}:${appConfig.basicAuthDevUser.password}`);
browser.cdp('Network', 'setExtraHTTPHeaders', {
headers: {
Authorization: `Basic ${encodedCredentials}`,
},
});
More on using devtools with wdio:
https://webdriver.io/docs/devtools-service/
More on chrome specific capabilites:
https://chromedevtools.github.io/devtools-protocol/tot/Network/
I was able to find the solution to pass a custom header while opening my webpage.
I am using ChromeDevTools service which is supported by webdriverio v5, using its method
browser.cdp(domain, command, parameters);
For the domain, command, and parameters please visit devtools protocol below:-
https://chromedevtools.github.io/devtools-protocol/

Insert text into an existing / external draftjs textfield

I'm working on an application which needs to insert text into a contenteditable="true" div (a Draftjs based textfield to be precise).
Now I am aware that Draft.js uses react and that it should be used that way, but in this case, the application already exists and this is a third party electron app that works with it.
I'm working on in-line notification replying on macOS, so I need that reply text to be pasted inside the draftJS field, however, when I do so using:
document.querySelector('div[contenteditable="true"]').focus();
document.execCommand('insertText', false, 'message');
It throws an error:
I was able to make it work using:
const event = document.createEvent('TextEvent');
event.initTextEvent('textInput', true, true, window, 'message', 0, locale);
but this API is deprecated and doesn't work properly if the message contains an emoji.
Is there any way to do this that doesn't cause an error?
I found out that the new API that is supposed to replace initTextEvent is just new Event() (see docs), but I can't find out if it supports textInput events.
To play around with it you can just go to https://draftjs.org/ and play with it in chrome dev tools.
I would really appreciate some help here as I don't know what to do to make it work anymore. Also, I know people are a fan of jquery, but I'd prefer a native js solution (although any solution is welcome).
edit:
Please note:
I'm not using react, the input field I want to modify (draftjs) is using react and I want to input text into it using native js.
edit 2:
For anyone else coming across this issue, I wanted to insert text into the Facebook messenger text field (which uses Draftjs).
I managed to find a working workaround.
It does use the deprecated API (event.initTextEvent), but it's the only way that I've found that works, even with emoji. Please do post an answer if you have a better solution to this.
It works like this:
async function sendReply(message: string): Promise<void> {
const inputField = document.querySelector('[contenteditable="true"]') as HTMLElement;
if (inputField) {
const previousMessage = inputField.textContent;
// Send message
inputField.focus();
await insertMessageText(message, inputField);
(await elementReady('._30yy._38lh._39bl')).click();
// Restore (possible) previous message
if (previousMessage) {
insertMessageText(previousMessage, inputField);
}
}
}
function insertMessageText(text: string, inputField: HTMLElement): void {
// Workaround: insert placeholder value to get execCommand working
if (!inputField.textContent) {
const event = document.createEvent('TextEvent');
event.initTextEvent('textInput', true, true, window, '_', 0, '');
inputField.dispatchEvent(event);
}
document.execCommand('selectAll', false, undefined);
document.execCommand('insertText', false, text);
}
This is typescript code, so you might want to change it up to use js.
It works by inserting a placeholder value inside the textField using event.initTextEvent, and then replacing that text with:
document.execCommand('selectAll', false, undefined);
document.execCommand('insertText', false, 'text');
tested in Chrome: Version 71.0.3578.98
Although the question was asked a long ago and #JoniVR found a workaround, this may help someone else.
I was also having a similar problem while working on an extension. I also tried the method document.execCommand('insertText', false, text). It worked on LinkedIn but not on Facebook. It was inserting text in the wrong node. Although document.execCommand API works in some places, it's obsolete now.
For Facebook and any other sites using drafjs editor, We need to dispatch a paste event using dataTransfer and clipBoardEvent APIs to make draftjs think that the text is pasted and process accordingly.
const dataTransfer = new DataTransfer();
function dispatchPaste(target, text) {
// this may be 'text/html' if it's required
dataTransfer.setData('text/plain', text);
target.dispatchEvent(
new ClipboardEvent('paste', {
clipboardData: dataTransfer,
// need these for the event to reach Draft paste handler
bubbles: true,
cancelable: true
})
);
// clear DataTransfer Data
dataTransfer.clearData();
}
Check this link in case more info needed.

Getting the contents of the toolbar search box using the Mozilla Firefox Add-on SDK

I am developing a Firefox addon and I was wondering how to get the contents of the search box in the toolbar using the Mozila Addon SDK? I finally found the chrome URL where it resides (at least I think: chrome://browser/content/search/...), but I’m still a little unsure as to how to reference this to get the contents of the search box into my addon. I tried: document.getAnonymousElementByAttribute(this, "anonid", "searchbar-textbox"); but this gives a “document is not defined” error, probably because Firefox has no idea what ‘searchbar-textbox’ is and this is outside the scope of the addon (in a different ‘document’). I’m relatively new to addon development, so there’s probably a fairly straight forward way to do this, it is just that this solution is unknown to me. Thanks.
Your "main" module (and other lib/ modules) do not have any document attached. You need to first use some low-level API such as the window/utils .getMostRecentBrowserWindow() function to obtain the DOMWindow for the active browser window. After that it's just getting the #searchbar element and checking the .value property (exposed through XBL).
Complete example:
const {getMostRecentBrowserWindow} = require("window/utils");
require("sdk/widget").Widget({
id: "log-search-field",
label: "Log Search Field",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function() {
let win = getMostRecentBrowserWindow();
console.error("Search text: " + win.document.getElementById("searchbar").value);
}
});

Categories

Resources