Skip to content
This repository has been archived by the owner on Feb 4, 2021. It is now read-only.

Commit

Permalink
Switch to a non-binary live-state
Browse files Browse the repository at this point in the history
  • Loading branch information
freaktechnik committed May 1, 2016
1 parent 73f4a0c commit 60aab90
Show file tree
Hide file tree
Showing 29 changed files with 290 additions and 241 deletions.
3 changes: 2 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = function(grunt) {
dependencies.push("crypt/**/*");

grunt.initConfig({
preVersion: 2,
pkg: pkg,
firefoxBinary: process.env.JPM_FIREFOX_BINARY || '/usr/bin/firefox-trunk',
banner:
Expand Down Expand Up @@ -210,7 +211,7 @@ module.exports = function(grunt) {
srcDir: ".",
destDir: "build/",
add: {
"version": "<%= pkg.version %>-pre1"
"version": "<%= pkg.version %>-pre<%= preVersion %>"
}
},
build: {
Expand Down
28 changes: 14 additions & 14 deletions data/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,11 +140,11 @@ const insertBefore = (parent, node, uname) => {
};

var insertChannel = (channel, node) => {
if((channel.live && !channel.state.enabled) || (channel.state.enabled && nonLiveDisplay === 0))
if(channel.live.isLive && (channel.live.state <= 0 || nonLiveDisplay === 0))
insertBefore(live, node, channel.uname);
else if(channel.state.enabled && nonLiveDisplay == 1)
else if(channel.live.isLive && nonLiveDisplay == 1)
insertBefore(secondaryLive, node, channel.uname);
else if(channel.state.enabled && nonLiveDisplay == 2)
else if(channel.live.isLive && nonLiveDisplay == 2)
insertBefore(distinct, node, channel.uname);
else
insertBefore(offline, node, channel.uname);
Expand Down Expand Up @@ -201,9 +201,9 @@ var buildChannel = (channel, unspecific = false) => {
channelNode.querySelector("a > img").setAttribute("src", channel.thumbnail);
channelNode.querySelector(".name").textContent = channel.uname;
channelNode.querySelector(".title").textContent = channel.title;
channelNode.querySelector(".alternate-name").textContent = channel.state.alternateUsername;
toggle(channelNode.querySelector(".nonlivename"), channel.state.alternateUsername !== "");
toggle(channelNode.querySelector(".rebroadcast"), channel.state.state == 2);
channelNode.querySelector(".alternate-name").textContent = channel.live.alternateUsername;
toggle(channelNode.querySelector(".nonlivename"), channel.live.alternateUsername !== "");
toggle(channelNode.querySelector(".rebroadcast"), channel.live.state == 2);
if(!("viewers" in channel) || channel.viewers < 0)
hide(channelNode.querySelector(".viewersWrapper"));
channelNode.querySelector(".viewers").textContent = channel.viewers;
Expand All @@ -219,11 +219,11 @@ var buildChannel = (channel, unspecific = false) => {
else {
channelNode.id = EXPLORE_ID_PREFIX+channel.login;
channelNode.dataset.url = channel.url[0];
channelNode.querySelector("a").addEventListener("click", openUrl.bind(null, channel.live? channel.url[0] : channel.archiveUrl, false));
channelNode.querySelector("a").addEventListener("click", openUrl.bind(null, channel.live.isLive ? channel.url[0] : channel.archiveUrl, false));
}
channelNode.addEventListener("contextmenu", contextMenuListener);

if(channel.state.enabled)
if(channel.live.state > 0)
channelNode.classList.add("nonlive");

return channelNode;
Expand All @@ -239,7 +239,7 @@ var addChannel = (channel) => {

insertChannel(channel, channelNode);
hideNoChannels();
if(channel.live)
if(channel.live.isLive)
hideNoOnline();
};

Expand Down Expand Up @@ -271,21 +271,21 @@ var updateNodeContent = (channel) => {

titleNode.textContent = channel.title;
nameNode.textContent = channel.uname;
channelNode.querySelector(".alternate-name").textContent = channel.state.alternateUsername;
toggle(channelNode.querySelector(".nonlivename"), channel.state.alternateUsername !== "");
toggle(channelNode.querySelector(".rebroadcast"), channel.state.state == 2);
channelNode.querySelector(".alternate-name").textContent = channel.live.alternateUsername;
toggle(channelNode.querySelector(".nonlivename"), channel.live.alternateUsername !== "");
toggle(channelNode.querySelector(".rebroadcast"), channel.live.state == 2);

viewers.textContent = channel.viewers;
toggle(channelNode.querySelector(".viewersWrapper"), ("viewers" in channel) && channel.viewers > 0);

category.textContent = channel.category;
toggle(channelNode.querySelector(".categoryWrapper"), !!channel.category);

channelNode.classList.toggle("nonlive", channel.state.enabled);
channelNode.classList.toggle("nonlive", channel.live.state > 0);

// only update images if the user is online to avoid broken images
if(navigator.onLine) {
if(channel.live || channel.state.enabled)
if(channel.live.isLive)
channelNode.querySelector("a>img").setAttribute("src", channel.thumbnail+"?timestamp="+Date.now());

channelNode.querySelector("a div img").srcset = Object.keys(channel.image)
Expand Down
28 changes: 15 additions & 13 deletions lib/channel/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const { window } = require("sdk/addon/window"),
const { merge, omit } = require("sdk/util/object");
const { LiveState } = require("./live-state");

const ITEM_ARGS = [ "login", "type", "id", "state" ];
const ITEM_ARGS = [ "login", "type", "id", "live" ];

const Item = newClass(
/** @lends module:channel/core~Item.prototype */
Expand Down Expand Up @@ -204,17 +204,11 @@ const Channel = newClass(

this.lastModified = Date.now();
if(state)
this.state = LiveState.deserialize(state);
this.live = LiveState.deserialize(state);
else
this.state = new LiveState();
this.live = new LiveState();
},
// properties
/**
* Indicates if the channel is live.
* @type {boolean}
* @default false
*/
live: false,
/**
* The title of the live broadcast
* @type {string}
Expand Down Expand Up @@ -279,15 +273,23 @@ const Channel = newClass(
* @default false
*/
mature: false,
_live: null,
/**
* @type {module:channel/live-state.LiveState}
* @default null
*/
state: null,
get live() {
return this._live;
},
set live(val) {
if(val instanceof LiveState)
this._live = val;
else
throw new TypeError("Trying to set the live state to something that isn't a LiveState");
},
/**
* Serialized version of {@link module:channel/core.Channel}
* @typedef {module:channel/core~SerializedItem} SerializedChannel
* @property {boolean} live
* @property {string} title
* @property {number} viewers
* @property {string} thumbnail
Expand All @@ -298,6 +300,7 @@ const Channel = newClass(
* @property {string} category
* @property {string} intent
* @proeprty {boolean} mature
* @property {module:channel/live-state~SerializedLiveState} live
*/
/**
* Serialize the item into a normal object
Expand All @@ -306,7 +309,6 @@ const Channel = newClass(
*/
serialize() {
return Object.assign(Item.prototype.serialize.call(this), {
live: this.live,
title: this.title,
viewers: this.viewers,
thumbnail: this.thumbnail,
Expand All @@ -317,7 +319,7 @@ const Channel = newClass(
category: this.category,
intent: this.intent,
mature: this.mature,
state: this.state.serialize()
live: this.live.serialize()
});
}
});
Expand Down
5 changes: 3 additions & 2 deletions lib/channel/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const { indexedDB, IDBKeyRange } = require("sdk/indexed-db"),
{ prefs } = require("sdk/simple-prefs");

const { Channel, User } = require("./core");
const { LiveState } = require("./live-state");

const providers = require("../providers");

Expand Down Expand Up @@ -171,7 +172,7 @@ ChannelList.prototype.openDB = function(name, dontTry = false) {

if(cursor) {
if(cursor.value.lastModified < minDate) {
cursor.value.live = false;
cursor.value.live.state = LiveState.OFFLINE;
cursor.update(cursor.value);
}
cursor.continue();
Expand Down Expand Up @@ -632,7 +633,7 @@ ChannelList.prototype.userExists = function(id, type) {
*/
ChannelList.prototype.liveStatus = async(function*(type) {
let channels = yield this.getChannelsByType(type);
return channels.some((channel) => channel.live);
return channels.some((channel) => channel.live.isLive());
});

/**
Expand Down
83 changes: 59 additions & 24 deletions lib/channel/live-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,45 @@

const { Class: newClass } = require("sdk/core/heritage");
const { merge, omit } = require("sdk/util/object");
const { prefs } = require("sdk/simple-prefs");

const IGNORED_PROPERTIES = [ "state", "enabled" ];
const IGNORED_PROPERTIES = [ "state", "isLive" ];

/**
* @typedef {number} LiveStateIndicator
*/
/**
* @typedef {Object} SerializedLiveState
* @property {module:channel/live-state~LiveStateIndicator} state
* @property {boolean} enabled
* @property {string} alternateUsername
* @property {string} alternateURL
* @see {@link module:channel/live-state.LiveState}
*/

const DISABLED = 0;
const OFFLINE = -1;
const LIVE = 0;
const REDIRECT = 1;
const REBROADCAST = 2;

/**
* Constant for how the live state is to be interpreted in a boolean scenario
* @typedef {number} LiveStateInterpretation
*/
const TOWARD_LIVE = 0;
const TOWARD_OFFLINE = 1;

const getDefaultInterpretation = () => parseInt(prefs.panel_nonlive, 10) < 3 ? TOWARD_LIVE : TOWARD_OFFLINE;

const LiveState = newClass(
/** @lends module:channel/live-state.LiveState.prototype */
{
/**
* Used to describe the exact state of a stream. Sometimes streams are marked
* as rebroadcasts or are a re-stream from a different source.
* @constructs
* @argument {module:channel/live-state~LiveStateIndicator} [state = {@link module:channel/live-state.LiveState.DISABLED}]
* @argument {module:channel/live-state~LiveStateIndicator} [state = {@link module:channel/live-state.LiveState.OFFLINE}]
*/
initialize(state = DISABLED) {
initialize(state = OFFLINE) {
this._state = state;
},
/**
Expand All @@ -49,50 +59,72 @@ const LiveState = newClass(
return this._state;
},
/**
* Indicates if the LiveState is in a special state.
* @type {boolean}
* @readonly
* The default interpretation mode based on a user's preference.
* @type {module:channel/live-state~LiveStateInterpretation}
*/
get enabled() {
return this.state !== DISABLED;
get defaultInterpretation() {
return getDefaultInterpretation();
},
alternateUsername: "",
alternateURL: "",
/**
* Disable the LiveState, so reset its state to {@link module:channel/live-state.LiveState.DISABLED}.
*/
disable() {
this._state = DISABLED;
},
/**
* Serialize the LiveState.
* @return {module:channel/live-state~SerializedLiveState}
*/
serialize() {
return {
state: this.state,
enabled: this.enabled,
alternateUsername: this.alternateUsername,
alternateURL: this.alternateURL
alternateURL: this.alternateURL,
isLive: this.isLive()
};
},
/**
* Interpret the live state to a boolean decision
* @argument {module:channel/live-state~LiveStateInterpretation} [interpretation]
* @return {boolean}
*/
isLive(interpretation = getDefaultInterpretation()) {
if(interpretation === TOWARD_LIVE)
return this.state !== OFFLINE;
else if(interpretation === TOWARD_OFFLINE)
return this.state === LIVE;
},
/**
* Set the state to live or not live. Simple as can be.
* @argument {boolean} isLive
*/
setLive(live) {
this._state = live ? LIVE : OFFLINE;
this.alternateUsername = "";
this.alternateURL = "";
}
});
/**
* Indicates that the channel is in a regular state.
* Indicates that the channel is offline.
* @const
* @type {module:channel/live-state~LiveStateIndicator}
* @alias module:channel/live-state.LiveState.OFFLINE
* @default 0
* @see {@link module:channel/live-state.LiveState.REDIRECT}, {@link module:channel/live-state.LiveState.REBROADCAST}, {@link module:channel/live-state.LiveState.LIVE}
*/
LiveState.OFFLINE = OFFLINE;
/**
* Indicates that the channel is live.
* @const
* @type {module:channel/live-state~LiveStateIndicator}
* @alias module:channel/live-state.LiveState.DISABLED
* @alias module:channel/live-state.LiveState.LIVE
* @default 0
* @see {@link module:channel/live-state.LiveState.REDIRECT}, {@link module:channel/live-state.LiveState.REBROADCAST}
* @see {@link module:channel/live-state.LiveState.REDIRECT}, {@link module:channel/live-state.LiveState.REBROADCAST}, {@link module:channel/live-state.LiveState.OFFLINE}
*/
LiveState.DISABLED = DISABLED;
LiveState.LIVE = LIVE;
/**
* Indicates the channel is hosting another channel or similar.
* @const
* @type {module:channel/live-state~LiveStateIndicator}
* @alias module:channel/live-state.LiveState.REDIRECT
* @default 1
* @see {@link module:channel/live-state.LiveState.DISABLED}, {@link module:channel/live-state.LiveState.REBROADCAST}
* @see {@link module:channel/live-state.LiveState.LIVE}, {@link module:channel/live-state.LiveState.REBROADCAST}, {@link module:channel/live-state.LiveState.OFFLINE}
*/
LiveState.REDIRECT = REDIRECT;
/**
Expand All @@ -101,10 +133,13 @@ LiveState.REDIRECT = REDIRECT;
* @type {module:channel/live-state~LiveStateIndicator}
* @alias module:channel/live-state.LiveState.REBROADCAST
* @default 2
* @see {@link module:channel/live-state.LiveState.DISABLED}, {@link module:channel/live-state.LiveState.REDIRECT}
* @see {@link module:channel/live-state.LiveState.LIVE}, {@link module:channel/live-state.LiveState.REDIRECT}, {@link module:channel/live-state.LiveState.OFFLINE}
*/
LiveState.REBROADCAST = REBROADCAST;

LiveState.TOWARD_LIVE = TOWARD_LIVE;
LiveState.TOWARD_OFFLINE = TOWARD_OFFLINE;

/**
* @alias module:channel/live-state.LiveState.deserialize
* @argument {module:channel/live-state~SerializedLiveState} serializedLiveState
Expand Down
7 changes: 4 additions & 3 deletions lib/channel/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
var tabs = require("sdk/tabs");
const livestreamer = require("../livestreamer");
const { when } = require("sdk/event/utils");
const { LiveState } = require("./live-state");

/**
* Opens the given channel in a new tab, unless there is already a tab open for
Expand All @@ -25,14 +26,14 @@ exports.selectOrOpenTab = function selectOrOpenTab(channel, what) {

if(what === "chat")
toCheck.push(channel.chatUrl);
else if(what === "archive" || !channel.live)
else if(what === "archive" || !channel.live.isLive())
toCheck.push(channel.archiveUrl);
else {
toCheck = channel.url;

if(what === "livestreamer" || livestreamer.default) {
if(channel.state.enabled && channel.state.alternateURL !== "")
toCheck = [channel.state.alternateURL];
if(channel.live.state > LiveState.LIVE && channel.live.alternateURL !== "")
toCheck = [channel.live.alternateURL];
return livestreamer.launch(toCheck[0]);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/list/firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ PanelList.prototype.setNonLiveDisplay = function(style) {

PanelList.prototype.addChannels = function(channels) {
channels.forEach(function(chan) {
if(chan.live) {
if(chan.live.isLive()) {
this.live.add(chan.id);
}
}, this);
Expand Down

0 comments on commit 60aab90

Please sign in to comment.