Thanks for your interest in building a remote for Mote.io!
Here's how you can get your remote into the production version of the Mote.io extesion:
- Fork this repository
- Create a remote
- Submit a pull request
I'll review your code, merge your remote in, and then deploy it to the world!
Mote.io remotes work by clicking and inspecting objects in the DOM. When a button is pressed on the phone, it fires a function which should probably click something on the page.
It's annoying to define a remote, reload the extension, launch the app, sync, and press the button on the phone just to test if a function works.
Instead, this is how I develop remotes:
- Test all of my button functions in the Chrome console before even begining to write the config file. This is identical to the environment the functions will be called in when triggered from the phone. If it works in console, it will work in
mote.io.remote
. These functions can be as simple as$('#playerPlay').click();
- Create a really simple remote with just buttons and test it on the phone
- Test functions to find now playing objects / states in the Chrome console (like #1). These may be like:
$('#now-playing').text().trim();
- I go back and add update(), notify(), and updateButton() methods and test it on the phone
You can also fire the button functions manually from the console once they have been added to mote.io.remote like so:
mote.io.remote.blocks[0].data[0].press();
- Fork this repository
- Disable production extension
- Load it as an unpacked extension in Chrome
- Visit the start page to make sure the unpacked extension works
- First, create a file in the
/remotes
directory with a descriptive name. - Then, add an entry to
manifest.json
for the site you want to support.
The entry should look something like this:
{
"matches": [
"http://www.pandora.com/*"
],
"js": [
"moteio.js",
"remotes/pandora.js"
],
"run_at": "document_start"
}
Chrome extensions are a hassle to refresh. You need to visit chrome://extensions
and refresh the page to update your extension. You can read more about refreshing extensions here.
You also may try this extension that adds a shortcut to reload extensions.
Check out extra section at the bottom of this doc for some solutions to common questions.
You can find many examplees of remotes in the /remotes directory. A remote file looks like so:
exec(function(){
mote.io.remote = {
api_version: '0.1',
app_name: 'Vimeo',
action: 'watching',
twitter: 'vimeo',
display_input: true,
init: function() {...}
update: function(force) {...},
blocks: [...]
};
});
Every remote file must be wrapped in the exec(function(){...});
call.
This function allows the javascript code to run at the document level. This means any variable you define within this function is going to be in the global scope!
Property | Type | Required | Notes |
---|---|---|---|
api_version | string | Yes | Should be '0.1' |
app_name | string | Yes | Appears at the top of the app, as well as in status updates. Keep it short. |
action | string | if notify.share is true | The verb that will appear in status updates. Example values are "watching" and "listening to". |
string | if notify.share is true | The @handle mentioned in Twitter share status updates. | |
display_input | boolean | Default is false. Enabling this will show an icon overlay over the web page when a button is tapped. | |
init | function | A function called after a phone has connected. | |
update | function | A function called by the plugin javascript to update the remote. | |
blocks | array | Yes | An array of objects containing the remote layout . |
Notify is the area in which app notifications are shown.
Property | Type | Required | Notes |
---|---|---|---|
type | string | Yes | Must be 'notify' |
share | boolean | Determines if Twitter and Facebook icons are shown. mote.io.remote.action and mote.io.remote.twitter must be defined if this is true. |
blocks: [
{
type: 'notify'
share: true
},
...
]
Search displays a text box with a search icon
Property | Type | Required | Notes |
---|---|---|---|
type | string | Yes | Must be 'search' |
action | function | Yes | A function to be called when the user submits a search query. The query is sent as the first param of the function. |
blocks: [
{
type: 'search',
action: function(query) {
alert(query);
}
}
...
]
The buttons type represents a row of buttons.
Property | Type | Required | Notes |
---|---|---|---|
type | string | Yes | Must be 'buttons' |
data | array | Yes | An array of button objects. Buttons are aligned from left to right but always centered on screen. |
blocks: [
{
type: 'buttons',
data: [
{...},
{...},
{...}
]
},
...
]
The yellow lines here represent individual blocks of buttons.
Data is an array of button objects. Button objects have the following properties:
Property | Type | Required | Notes |
---|---|---|---|
press | function | Yes | A function to call when the button is pressed |
icon | string | Yes | This is an icon from font-awesome. Do not provide the text "icon-" as it will be added automatically. |
hash | hash | This is a button identifier used in button updates (read more below) |
Here is the middle row of the image above represented in javascript:
blocks: [
{
type: 'buttons',
data: [
{
press: function () {
alert('left pressed');
},
icon: 'chevron-left'
hash: 'up'
},
{
press: function () {
alert('middle pressed');
},
icon: 'circle-blank'
hash: 'go'
},
{
press: function () {
alert('right pressed');
},
icon: 'chevron-right'
hash: 'right'
},
]
},
...
]
Select represents a select box in the app.
Property | Type | Required | Notes |
---|---|---|---|
type | string | Yes | Must be 'select' |
data | array | Yes | An array of select option objects. |
{
type: 'select',
data: [
{...},
{...}
]
}
Select.data is an array of select option objects. Select option objects have the following properties:
Property | Type | Required | Notes |
---|---|---|---|
text | string | Yes | The option text |
action | array | Yes | A function to fire when the select button is pressed |
optgroup | string | Groups select option objects under a parent with this value |
{
type: 'select',
data: [
{
optgroup: 'Latest',
text: 'Latest',
action: function() {
window.location = "/latest";
}
},
{
optgroup: 'Latest',
text: 'Freshest',
action: function() {
window.location = "/latest/fresh";
}
},
...
}
Notify sends information to the notify block about what to display.
Parameters | Type | Required | Notes |
---|---|---|---|
line1 | string | Yes | The first line of text |
line2 | string | The second line of text | |
image | string | Yes | The url of an image to display next to text. Resized to 50px x 50px |
url | string | Yes | A permalink to the current playing item. Not the current window.location, but a link to the single item that is playing right now. |
force | boolean | Yes | Pass the value of force from mote.io.remote.update(force) . Must be false if used outside of the update() context. |
mote.io.remote = {
update: function(force) {
var thisArtist = $($('#player-nowplaying a')[3]).text(),
thisSong = $($('#player-nowplaying a')[4]).text(),
thisImage = extractUrl($('.haarp-active.section-track').find('.readpost > span').css('background-image')),
thisPerma = window.location.origin + $('.haarp-active.section-track').find('a.track').attr('href');
mote.io.notify(thisArtist, thisSong, thisImage, thisPerma, force);
}
}
The update button method allows you to change the color and icon of a button on a remote.
Parameters | Type | Required | Notes |
---|---|---|---|
button_hash | string | Yes | The hash identifier of the button. Make sure you assign this variable in the button object. |
icon | string | Yes | The new icon to display. |
color | string | Yes | The button icon color. A 6 character hex code like #000000 or #ffffff |
force | boolean | Yes | Pass the value of force from mote.io.remote.update(force) . Must be false if used outside of the update() context. |
mote.io.remote = {
update: function(force) {
if($('#playerFav').hasClass('fav-on')) {
mote.io.updateButton('heart', null, '#ff0000', force);
} else {
mote.io.updateButton('heart', null, '#434345', force);
}
}
}
The mote.io plugin provides you with jQuery for free by using the jQ
variable. Not all of the examples may use jQ
. They may access the standard $
which is actually provided by the website the code is injected onto, not the mote.io extension.
A remote is only sent to the client once, when it is found on the webpage. Something like the following will work just fine.
setTimeout(function(){
mote.io.remote = {};
}, 5000);
Once the remote is sent, you can only update the button colors, icons, and notification text.
However, sometimes you just need to send the whole remote over. This is usually because the website you're building a remote for is a single page app.
Use the following method to resend mote.io.remote
to the phone. This function has no parameters, it simply looks for mote.io.remote
and sends it over.
mote.io.receiver.sendRemote();