#144 Notification toast when updating settings (and other things)
This commit is contained in:
parent
d6b2bd1d5e
commit
87b6bb6d85
47
index.js
47
index.js
@ -21,6 +21,7 @@ const ChannelDB = require("./src/dao/channel-db");
|
||||
const M3uService = require("./src/services/m3u-service");
|
||||
const FillerDB = require("./src/dao/filler-db");
|
||||
const TVGuideService = require("./src/tv-guide-service");
|
||||
const EventService = require("./src/services/event-service");
|
||||
const onShutdown = require("node-graceful-shutdown").onShutdown;
|
||||
|
||||
console.log(
|
||||
@ -76,6 +77,7 @@ db.connect(process.env.DATABASE, ['channels', 'plex-servers', 'ffmpeg-settings',
|
||||
fileCache = new FileCacheService( path.join(process.env.DATABASE, 'cache') );
|
||||
cacheImageService = new CacheImageService(db, fileCache);
|
||||
m3uService = new M3uService(channelDB, fileCache, channelCache)
|
||||
eventService = new EventService();
|
||||
|
||||
initDB(db, channelDB)
|
||||
|
||||
@ -165,6 +167,8 @@ xmltvInterval.startInterval()
|
||||
|
||||
let hdhr = HDHR(db, channelDB)
|
||||
let app = express()
|
||||
eventService.setup(app);
|
||||
|
||||
app.use(fileUpload({
|
||||
createParentPath: true
|
||||
}));
|
||||
@ -197,7 +201,7 @@ app.use('/favicon.svg', express.static(
|
||||
) );
|
||||
|
||||
// API Routers
|
||||
app.use(api.router(db, channelDB, fillerDB, xmltvInterval, guideService, m3uService ))
|
||||
app.use(api.router(db, channelDB, fillerDB, xmltvInterval, guideService, m3uService, eventService ))
|
||||
app.use('/api/cache/images', cacheImageService.apiRouters())
|
||||
|
||||
app.use(video.router( channelDB, fillerDB, db))
|
||||
@ -242,8 +246,49 @@ function initDB(db, channelDB) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
function _wait(t) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, t);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function sendEventAfterTime() {
|
||||
let t = (new Date()).getTime();
|
||||
await _wait(20000);
|
||||
eventService.push(
|
||||
"lifecycle",
|
||||
{
|
||||
"message": `Server Started`,
|
||||
"detail" : {
|
||||
"time": t,
|
||||
},
|
||||
"level" : "success"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
sendEventAfterTime();
|
||||
|
||||
|
||||
|
||||
|
||||
onShutdown("log" , [], async() => {
|
||||
let t = (new Date()).getTime();
|
||||
eventService.push(
|
||||
"lifecycle",
|
||||
{
|
||||
"message": `Initiated Server Shutdown`,
|
||||
"detail" : {
|
||||
"time": t,
|
||||
},
|
||||
"level" : "warning"
|
||||
}
|
||||
);
|
||||
|
||||
console.log("Received exit signal, attempting graceful shutdonw...");
|
||||
await _wait(2000);
|
||||
});
|
||||
onShutdown("xmltv-writer" , [], async() => {
|
||||
await xmltv.shutdown();
|
||||
|
||||
297
src/api.js
297
src/api.js
@ -12,9 +12,20 @@ const Plex = require("./plex.js");
|
||||
const timeSlotsService = require('./services/time-slots-service');
|
||||
const randomSlotsService = require('./services/random-slots-service');
|
||||
|
||||
function safeString(object) {
|
||||
let o = object;
|
||||
for(let i = 1; i < arguments.length; i++) {
|
||||
o = o[arguments[i]];
|
||||
if (typeof(o) === 'undefined') {
|
||||
return "missing";
|
||||
}
|
||||
}
|
||||
return String(o);
|
||||
}
|
||||
|
||||
module.exports = { router: api }
|
||||
function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService ) {
|
||||
const m3uService = _m3uService;
|
||||
function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService, eventService ) {
|
||||
let m3uService = _m3uService;
|
||||
const router = express.Router()
|
||||
const plexServerDB = new PlexServerDB(channelDB, channelCache, db);
|
||||
|
||||
@ -89,34 +100,113 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
}
|
||||
})
|
||||
router.delete('/api/plex-servers', async (req, res) => {
|
||||
let name = "unknown";
|
||||
try {
|
||||
let name = req.body.name;
|
||||
name = req.body.name;
|
||||
if (typeof(name) === 'undefined') {
|
||||
return res.status(400).send("Missing name");
|
||||
}
|
||||
let report = await plexServerDB.deleteServer(name);
|
||||
res.send(report)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": `Plex server ${name} removed.`,
|
||||
"module" : "plex-server",
|
||||
"detail" : {
|
||||
"serverName" : name,
|
||||
"action" : "delete"
|
||||
},
|
||||
"level" : "warn"
|
||||
}
|
||||
);
|
||||
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error deleting plex server.",
|
||||
"module" : "plex-server",
|
||||
"detail" : {
|
||||
"action": "delete",
|
||||
"serverName" : name,
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
router.post('/api/plex-servers', async (req, res) => {
|
||||
try {
|
||||
await plexServerDB.updateServer(req.body);
|
||||
res.status(204).send("Plex server updated.");;
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": `Plex server ${req.body.name} updated.`,
|
||||
"module" : "plex-server",
|
||||
"detail" : {
|
||||
"serverName" : req.body.name,
|
||||
"action" : "update"
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
console.error("Could not add plex server.", err);
|
||||
console.error("Could not update plex server.", err);
|
||||
res.status(400).send("Could not add plex server.");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error updating plex server.",
|
||||
"module" : "plex-server",
|
||||
"detail" : {
|
||||
"action": "update",
|
||||
"serverName" : safeString(req, "body", "name"),
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
router.put('/api/plex-servers', async (req, res) => {
|
||||
try {
|
||||
await plexServerDB.addServer(req.body);
|
||||
res.status(201).send("Plex server added.");;
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": `Plex server ${req.body.name} added.`,
|
||||
"module" : "plex-server",
|
||||
"detail" : {
|
||||
"serverName" : req.body.name,
|
||||
"action" : "add"
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
console.error("Could not add plex server.", err);
|
||||
res.status(400).send("Could not add plex server.");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error adding plex server.",
|
||||
"module" : "plex-server",
|
||||
"detail" : {
|
||||
"action": "add",
|
||||
"serverName" : safeString(req, "body", "name"),
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
}
|
||||
})
|
||||
|
||||
@ -341,10 +431,34 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
if (typeof(err) !== 'undefined') {
|
||||
return res.status(400).send(err);
|
||||
}
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "FFMPEG configuration updated.",
|
||||
"module" : "ffmpeg",
|
||||
"detail" : {
|
||||
"action" : "update"
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
res.send(ffmpeg)
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error updating FFMPEG configuration.",
|
||||
"module" : "ffmpeg",
|
||||
"detail" : {
|
||||
"action": "update",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
})
|
||||
router.post('/api/ffmpeg-settings', (req, res) => { // RESET
|
||||
@ -353,10 +467,34 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
ffmpeg.ffmpegPath = req.body.ffmpegPath;
|
||||
db['ffmpeg-settings'].update({ _id: req.body._id }, ffmpeg)
|
||||
ffmpeg = db['ffmpeg-settings'].find()[0]
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "FFMPEG configuration reset.",
|
||||
"module" : "ffmpeg",
|
||||
"detail" : {
|
||||
"action" : "reset"
|
||||
},
|
||||
"level" : "warning"
|
||||
}
|
||||
);
|
||||
res.send(ffmpeg)
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error reseting FFMPEG configuration.",
|
||||
"module" : "ffmpeg",
|
||||
"detail" : {
|
||||
"action": "reset",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
@ -384,9 +522,34 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
db['plex-settings'].update({ _id: req.body._id }, req.body)
|
||||
let plex = db['plex-settings'].find()[0]
|
||||
res.send(plex)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Plex configuration updated.",
|
||||
"module" : "plex",
|
||||
"detail" : {
|
||||
"action" : "update"
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error updating Plex configuration",
|
||||
"module" : "plex",
|
||||
"detail" : {
|
||||
"action": "update",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
@ -415,9 +578,35 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
})
|
||||
let plex = db['plex-settings'].find()[0]
|
||||
res.send(plex)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Plex configuration reset.",
|
||||
"module" : "plex",
|
||||
"detail" : {
|
||||
"action" : "reset"
|
||||
},
|
||||
"level" : "warning"
|
||||
}
|
||||
);
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error reseting Plex configuration",
|
||||
"module" : "plex",
|
||||
"detail" : {
|
||||
"action": "reset",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
@ -458,10 +647,35 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
);
|
||||
xmltv = db['xmltv-settings'].find()[0]
|
||||
res.send(xmltv)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "xmltv settings updated.",
|
||||
"module" : "xmltv",
|
||||
"detail" : {
|
||||
"action" : "update"
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
updateXmltv()
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error updating xmltv configuration",
|
||||
"module" : "xmltv",
|
||||
"detail" : {
|
||||
"action": "update",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
@ -475,10 +689,35 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
})
|
||||
var xmltv = db['xmltv-settings'].find()[0]
|
||||
res.send(xmltv)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "xmltv settings reset.",
|
||||
"module" : "xmltv",
|
||||
"detail" : {
|
||||
"action" : "reset"
|
||||
},
|
||||
"level" : "warning"
|
||||
}
|
||||
);
|
||||
|
||||
updateXmltv()
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error reseting xmltv configuration",
|
||||
"module" : "xmltv",
|
||||
"detail" : {
|
||||
"action": "reset",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
@ -537,9 +776,34 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
db['hdhr-settings'].update({ _id: req.body._id }, req.body)
|
||||
let hdhr = db['hdhr-settings'].find()[0]
|
||||
res.send(hdhr)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "HDHR configuration updated.",
|
||||
"module" : "hdhr",
|
||||
"detail" : {
|
||||
"action" : "update"
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error updating HDHR configuration",
|
||||
"module" : "hdhr",
|
||||
"detail" : {
|
||||
"action": "action",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
@ -552,9 +816,34 @@ function api(db, channelDB, fillerDB, xmltvInterval, guideService, _m3uService
|
||||
})
|
||||
var hdhr = db['hdhr-settings'].find()[0]
|
||||
res.send(hdhr)
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "HDHR configuration reset.",
|
||||
"module" : "hdhr",
|
||||
"detail" : {
|
||||
"action" : "reset"
|
||||
},
|
||||
"level" : "warning"
|
||||
}
|
||||
);
|
||||
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
res.status(500).send("error");
|
||||
eventService.push(
|
||||
"settings-update",
|
||||
{
|
||||
"message": "Error reseting HDHR configuration",
|
||||
"module" : "hdhr",
|
||||
"detail" : {
|
||||
"action": "reset",
|
||||
"error" : safeString(err, "message"),
|
||||
},
|
||||
"level" : "danger"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
47
src/services/event-service.js
Normal file
47
src/services/event-service.js
Normal file
@ -0,0 +1,47 @@
|
||||
const EventEmitter = require("events");
|
||||
|
||||
class EventsService {
|
||||
constructor() {
|
||||
this.stream = new EventEmitter();
|
||||
let that = this;
|
||||
let fun = () => {
|
||||
that.push( "heartbeat", "{}");
|
||||
setTimeout(fun, 5000)
|
||||
};
|
||||
fun();
|
||||
|
||||
}
|
||||
|
||||
setup(app) {
|
||||
app.get("/api/events", (request, response) => {
|
||||
console.log("Open event channel.");
|
||||
response.writeHead(200, {
|
||||
"Content-Type" : "text/event-stream",
|
||||
"Cache-Control" : "no-cache",
|
||||
"connection" : "keep-alive",
|
||||
} );
|
||||
let listener = (event,data) => {
|
||||
//console.log( String(event) + " " + JSON.stringify(data) );
|
||||
response.write("event: " + String(event) + "\ndata: "
|
||||
+ JSON.stringify(data) + "\nretry: 5000\n\n" );
|
||||
};
|
||||
|
||||
this.stream.on("push", listener );
|
||||
response.on( "close", () => {
|
||||
console.log("Remove event channel.");
|
||||
this.stream.removeListener("push", listener);
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
push(event, data) {
|
||||
if (typeof(data.message) !== 'undefined') {
|
||||
console.log("Push event: " + data.message );
|
||||
}
|
||||
this.stream.emit("push", event, data );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = EventsService;
|
||||
@ -7,7 +7,7 @@ class TVGuideService
|
||||
/****
|
||||
*
|
||||
**/
|
||||
constructor(xmltv, db, cacheImageService) {
|
||||
constructor(xmltv, db, cacheImageService, eventService) {
|
||||
this.cached = null;
|
||||
this.lastUpdate = 0;
|
||||
this.updateTime = 0;
|
||||
@ -19,6 +19,7 @@ class TVGuideService
|
||||
this.xmltv = xmltv;
|
||||
this.db = db;
|
||||
this.cacheImageService = cacheImageService;
|
||||
this.eventService = eventService;
|
||||
}
|
||||
|
||||
async get() {
|
||||
@ -44,6 +45,19 @@ class TVGuideService
|
||||
this.currentUpdate = this.updateTime;
|
||||
this.currentLimit = this.updateLimit;
|
||||
this.currentChannels = this.updateChannels;
|
||||
let t = "" + ( (new Date()) );
|
||||
eventService.push(
|
||||
"xmltv",
|
||||
{
|
||||
"message": `Started building tv-guide at = ${t}`,
|
||||
"module" : "xmltv",
|
||||
"detail" : {
|
||||
"time": new Date(),
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
|
||||
await this.buildIt();
|
||||
}
|
||||
await _wait(100);
|
||||
@ -353,6 +367,19 @@ class TVGuideService
|
||||
async refreshXML() {
|
||||
let xmltvSettings = this.db['xmltv-settings'].find()[0];
|
||||
await this.xmltv.WriteXMLTV(this.cached, xmltvSettings, async() => await this._throttle(), this.cacheImageService);
|
||||
let t = "" + ( (new Date()) );
|
||||
eventService.push(
|
||||
"xmltv",
|
||||
{
|
||||
"message": `XMLTV updated at server time = ${t}`,
|
||||
"module" : "xmltv",
|
||||
"detail" : {
|
||||
"time": new Date(),
|
||||
},
|
||||
"level" : "info"
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
async getStatus() {
|
||||
|
||||
@ -19,6 +19,7 @@ app.directive('plexLibrary', require('./directives/plex-library'))
|
||||
app.directive('programConfig', require('./directives/program-config'))
|
||||
app.directive('flexConfig', require('./directives/flex-config'))
|
||||
app.directive('timeSlotsTimeEditor', require('./directives/time-slots-time-editor'))
|
||||
app.directive('toastNotifications', require('./directives/toast-notifications'))
|
||||
app.directive('fillerConfig', require('./directives/filler-config'))
|
||||
app.directive('deleteFiller', require('./directives/delete-filler'))
|
||||
app.directive('frequencyTweak', require('./directives/frequency-tweak'))
|
||||
|
||||
116
web/directives/toast-notifications.js
Normal file
116
web/directives/toast-notifications.js
Normal file
@ -0,0 +1,116 @@
|
||||
module.exports = function ($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
templateUrl: 'templates/toast-notifications.html',
|
||||
replace: true,
|
||||
scope: {
|
||||
},
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
const FADE_IN_START = 100;
|
||||
const FADE_IN_END = 1000;
|
||||
const FADE_OUT_START = 10000;
|
||||
const TOTAL_DURATION = 11000;
|
||||
|
||||
|
||||
scope.toasts = [];
|
||||
|
||||
let eventSource = null;
|
||||
|
||||
let timerHandle = null;
|
||||
let refreshHandle = null;
|
||||
|
||||
|
||||
let setResetTimer = () => {
|
||||
if (timerHandle != null) {
|
||||
clearTimeout( timerHandle );
|
||||
}
|
||||
timerHandle = setTimeout( () => {
|
||||
scope.setup();
|
||||
} , 10000);
|
||||
};
|
||||
|
||||
let updateAfter = (wait) => {
|
||||
if (refreshHandle != null) {
|
||||
$timeout.cancel( refreshHandle );
|
||||
}
|
||||
refreshHandle = $timeout( ()=> updater(), wait );
|
||||
};
|
||||
|
||||
let updater = () => {
|
||||
let wait = 10000;
|
||||
let updatedToasts = [];
|
||||
try {
|
||||
let t = (new Date()).getTime();
|
||||
for (let i = 0; i < scope.toasts.length; i++) {
|
||||
let toast = scope.toasts[i];
|
||||
let diff = t - toast.time;
|
||||
if (diff < TOTAL_DURATION) {
|
||||
if (diff < FADE_IN_START) {
|
||||
toast.clazz = { "about-to-fade-in" : true }
|
||||
wait = Math.min( wait, FADE_IN_START - diff );
|
||||
} else if (diff < FADE_IN_END) {
|
||||
toast.clazz = { "fade-in" : true }
|
||||
wait = Math.min( wait, FADE_IN_END - diff );
|
||||
} else if (diff < FADE_OUT_START) {
|
||||
toast.clazz = {}
|
||||
wait = Math.min( wait, FADE_OUT_START - diff );
|
||||
} else {
|
||||
toast.clazz = { "fade-out" : true }
|
||||
wait = Math.min( wait, TOTAL_DURATION - diff );
|
||||
}
|
||||
toast.clazz[toast.deco] = true;
|
||||
updatedToasts.push(toast);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("error", err);
|
||||
}
|
||||
scope.toasts = updatedToasts;
|
||||
updateAfter(wait);
|
||||
};
|
||||
|
||||
let addToast = (toast) => {
|
||||
toast.time = (new Date()).getTime();
|
||||
toast.clazz= { "about-to-fade-in": true };
|
||||
toast.clazz[toast.deco] = true;
|
||||
scope.toasts.push(toast);
|
||||
$timeout( () => updateAfter(0) );
|
||||
};
|
||||
|
||||
let getDeco = (data) => {
|
||||
return "bg-" + data.level;
|
||||
}
|
||||
|
||||
scope.setup = () => {
|
||||
if (eventSource != null) {
|
||||
eventSource.close();
|
||||
eventSource = null;
|
||||
}
|
||||
setResetTimer();
|
||||
|
||||
eventSource = new EventSource("api/events");
|
||||
|
||||
eventSource.addEventListener("heartbeat", () => {
|
||||
setResetTimer();
|
||||
} );
|
||||
|
||||
let normalEvent = (title) => {
|
||||
return (event) => {
|
||||
let data = JSON.parse(event.data);
|
||||
addToast ( {
|
||||
title : title,
|
||||
text : data.message,
|
||||
deco: getDeco(data)
|
||||
} )
|
||||
};
|
||||
};
|
||||
|
||||
eventSource.addEventListener('settings-update', normalEvent("Settings Update") );
|
||||
eventSource.addEventListener('xmltv', normalEvent("TV Guide") );
|
||||
eventSource.addEventListener('lifecycle', normalEvent("Server") );
|
||||
};
|
||||
scope.setup();
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -43,6 +43,7 @@
|
||||
</span>
|
||||
<hr/>
|
||||
<div ng-view></div>
|
||||
<toast-notifications></toast-notifications>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
@ -357,6 +357,38 @@ div.programming-programs div.list-group-item {
|
||||
background : rgba(255,255,255, 0.1);
|
||||
}
|
||||
|
||||
.dizque-toast {
|
||||
margin-top: 0.2rem;
|
||||
padding: 0.5rem;
|
||||
background: #FFFFFF;
|
||||
border: 1px solid rgba(0,0,0,.1);
|
||||
border-radius: .25rem;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.dizque-toast.bg-warning {
|
||||
color: black
|
||||
}
|
||||
|
||||
.about-to-fade-in {
|
||||
opacity: 0.00;
|
||||
transition: opacity 1.00s ease-in-out;
|
||||
-moz-transition: opacity 1.00s ease-in-out;
|
||||
-webkit-transition: opacity 1.00s ease-in-out;
|
||||
}
|
||||
.fade-in {
|
||||
opacity: 0.95;
|
||||
transition: opacity 1.00s ease-in-out;
|
||||
-moz-transition: opacity 1.00s ease-in-out;
|
||||
-webkit-transition: opacity 1.00s ease-in-out;
|
||||
}
|
||||
|
||||
.fade-out {
|
||||
transition: opacity 1.00s ease-in-out;
|
||||
-moz-transition: opacity 1.00s ease-in-out;
|
||||
-webkit-transition: opacity 1.00s ease-in-out;
|
||||
opacity: 0.0;
|
||||
}
|
||||
|
||||
#dizquetv-logo {
|
||||
width: 1em;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<button class="pull-right btn btn-sm btn-success" style="margin-left: 5px;" ng-click="updateSettings(settings)">
|
||||
Update
|
||||
</button>
|
||||
<button class="pull-right btn btn-sm btn-info" ng-click="resetSettings(settings)">
|
||||
<button class="pull-right btn btn-sm btn-warning" ng-click="resetSettings(settings)">
|
||||
Reset Options
|
||||
</button>
|
||||
</h5>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<button class="pull-right btn btn-sm btn-success" style="margin-left: 5px;" ng-click="updateSettings(settings)">
|
||||
Update
|
||||
</button>
|
||||
<button class="pull-right btn btn-sm btn-info" ng-click="resetSettings(settings)">
|
||||
<button class="pull-right btn btn-sm btn-warning" ng-click="resetSettings(settings)">
|
||||
Reset Options
|
||||
</button>
|
||||
</h5>
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
<button class="pull-right btn btn-sm btn-success" style="margin-left: 5px;" ng-click="updateSettings(settings)">
|
||||
Update
|
||||
</button>
|
||||
<button class="pull-right btn btn-sm btn-info" ng-click="resetSettings(settings)">
|
||||
<button class="pull-right btn btn-sm btn-warning" ng-click="resetSettings(settings)">
|
||||
Reset Options
|
||||
</button>
|
||||
</h6>
|
||||
|
||||
11
web/public/templates/toast-notifications.html
Normal file
11
web/public/templates/toast-notifications.html
Normal file
@ -0,0 +1,11 @@
|
||||
<div style='position: fixed; top: 30px; right: 30px; width:400px; z-index: 1000000;'>
|
||||
|
||||
<div
|
||||
ng-repeat="toast in toasts track by $index"
|
||||
class="dizque-toast"
|
||||
ng-class="toast.clazz"
|
||||
>
|
||||
<strong>{{ toast.title }}</strong>
|
||||
<div>{{ toast.text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -4,7 +4,7 @@
|
||||
<button class="pull-right btn btn-sm btn-success" style="margin-left: 5px;" ng-click="updateSettings(settings)">
|
||||
Update
|
||||
</button>
|
||||
<button class="pull-right btn btn-sm btn-info" ng-click="resetSettings(settings)">
|
||||
<button class="pull-right btn btn-sm btn-warning" ng-click="resetSettings(settings)">
|
||||
Reset Options
|
||||
</button>
|
||||
</h5>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user