Show the timeline

This commit is contained in:
Feufochmar 2020-03-30 10:34:40 +02:00
parent 7e04869453
commit cb5977f910
6 changed files with 131 additions and 41 deletions

View File

@ -40,6 +40,10 @@ nav {
padding-bottom: 0.5em;
padding-left: 1em;
padding-right: 1em;
cursor: pointer;
}
.page-label:hover {
background-color: hsl(240, 10%, 75%);
}
.error {
@ -113,6 +117,12 @@ main {
align-items: stretch;
}
.timeline-prev-next {
display: flex;
flex-direction: row;
justify-content: space-around;
}
/* Other */
a:link {
color: hsl(220, 100%, 40%);
@ -151,7 +161,7 @@ li.actor-display {
background-color: hsl(240, 10%, 75%);
}
article.activity {
section.timeline-activity {
display: block;
border-style: solid;
border-width: thin;
@ -159,6 +169,10 @@ article.activity {
padding: 0.5em;
margin-top: 0.1em;
margin-bottom: 0.1em;
cursor: pointer;
}
section.timeline-activity:hover {
background-color: hsl(240, 10%, 75%);
}
section.actor-display {

View File

@ -31,7 +31,17 @@
<!-- Timelines -->
<section id="timeline" style="display:none;">
<section id="timeline-error" class="error"></section>
<section id="timeline-data" class="timeline"></section>
<section class="timeline">
<section class="timeline-prev-next">
<button id="timeline-prev-top" onclick="UI.prevTimeline();">Previous</button>
<button id="timeline-next-top" onclick="UI.nextTimeline();">Next</button>
</section>
<section id="timeline-data"></section>
<section class="timeline-prev-next">
<button id="timeline-prev-bottom" onclick="UI.prevTimeline();">Previous</button>
<button id="timeline-next-bottom" onclick="UI.nextTimeline();">Next</button>
</section>
</section>
</section>
<!-- Content pages -->
<section id="main-content">

View File

@ -3,8 +3,8 @@ const { app, BrowserWindow } = require('electron')
function createWindow () {
// Create the browser window.
const win = new BrowserWindow({
width: 800,
height: 600,
width: 1024,
height: 768,
webPreferences: {
nodeIntegration: true
}

122
render.js
View File

@ -10,7 +10,7 @@ const Elem = function(id) {
// Icon list
const Icons = {
'unknown-user': "/img/unknown-user.svg"
'unknown-user': "img/unknown-user.svg"
}
// To render elements that cannot be present in index.html from a model element
@ -50,6 +50,40 @@ const Render = {
}
str_data = str_data.replace(/[&<>"']/g, x => replace_map[x])
return str_data
},
// Activity in timeline
// By type of activity
timelineActivity: {
'Create': function(activity) {
var display = '<section class="timeline-activity" onclick="UI.showActivity(\'' + activity.id + '\');">'
+ 'New ' + activity.object.type + '<br/>'
+ '<strong>' + activity.actor.displayName() + '</strong><br/>'
if (activity.object.summary) {
display = display + '<em>' + activity.object.summary + '</em>'
} else {
display = display + '<em>No summary</em>'
}
display = display + '</section>'
return display
},
'Like': function(activity) {
return '<section class="timeline-activity" onclick="UI.showActivity(\'' + activity.id + '\');">'
+ 'Like <br/>'
+ '<strong>' + activity.actor.displayName() + '</strong>'
+ '</section>'
},
'Announce': function(activity) {
return '<section class="timeline-activity" onclick="UI.showActivity(\'' + activity.id + '\');">'
+ 'Announce <br/>'
+ '<strong>' + activity.actor.displayName() + '</strong>'
+ '</section>'
},
'Delete': function(activity) {
return '<section class="timeline-activity" onclick="UI.showActivity(\'' + activity.id + '\');">'
+ 'Delete <br/>'
+ '<strong>' + activity.actor.displayName() + '</strong>'
+ '</section>'
}
}
}
@ -60,6 +94,7 @@ const UI = {
current_context: 'my-inbox', // By default, show the inbox
is_connected: false, // Indicate if the user is connected
other_actor: new Actor(), // Other actor to display
timeline: new Timeline(), // Collection of activities to display in the central column
// Contextual methods
refresh_context: {
'send-message': function() {
@ -84,7 +119,7 @@ const UI = {
'my-outbox': function() {
UI.updateNav('outbox-selector')
if (UI.is_connected) {
UI.showTimeline(ConnectedUser.actor.urls.inbox, ConnectedUser.tokens.user.access_token)
UI.showTimeline(ConnectedUser.actor.urls.outbox, ConnectedUser.tokens.user.access_token)
UI.showPage('show-profile', ConnectedUser.actor)
} else {
UI.showTimeline(undefined, undefined)
@ -102,12 +137,13 @@ const UI = {
},
'other-profile': function() {
UI.updateNav(undefined)
UI.showPage('show-profile', UI.other_actor)
if (UI.other_actor.urls.outbox) {
UI.showTimeline(UI.other_actor.urls.outbox, undefined)
} else {
UI.displayTimelineError('Actor does not have a public outbox.')
UI.displayContentError('Actor does not have a public outbox.')
UI.showTimeline(undefined, undefined)
}
UI.showPage('show-profile', UI.other_actor)
}
},
// Page refresh methods
@ -211,7 +247,39 @@ const UI = {
if (url) {
Elem('timeline').style.display = 'block'
Elem('timeline-data').innerHTML = 'Loading collection...'
// TODO
Elem('timeline-prev-top').style.display = 'none'
Elem('timeline-prev-bottom').style.display = 'none'
Elem('timeline-next-top').style.display = 'none'
Elem('timeline-next-bottom').style.display = 'none'
UI.timeline = new Timeline()
UI.timeline.load(
url,
token,
function(load_ok, failure_message) {
if (load_ok) {
Elem('timeline-data').innerHTML = UI.timeline.activities.map(function(activity) {
if (Render.timelineActivity[activity.type]) {
return Render.timelineActivity[activity.type](activity)
} else {
return '<section class="timeline-activity">'
+ 'Other activity (' + activity.type + ')<br/>'
+ '<strong>' + activity.actor.displayName() + '</strong></section>'
}
}).join('')
if (UI.timeline.prev) {
Elem('timeline-prev-top').style.display = 'block'
Elem('timeline-prev-bottom').style.display = 'block'
}
if (UI.timeline.next) {
Elem('timeline-next-top').style.display = 'block'
Elem('timeline-next-bottom').style.display = 'block'
}
} else {
UI.displayTimelineError(failure_message)
Elem('timeline-data').innerHTML = ''
}
}
)
} else {
Elem('timeline').style.display = 'none'
}
@ -331,6 +399,21 @@ const UI = {
UI.displayContentError('Error when sending message: ' + failure_message)
}
})
},
// Timeline navigation
nextTimeline: function() {
if (UI.timeline.next) {
UI.showTimeline(UI.timeline.next, UI.timeline.token)
}
},
prevTimeline: function() {
if (UI.timeline.prev) {
UI.showTimeline(UI.timeline.prev, UI.timeline.token)
}
},
// Show contents of activities
showActivity: function(activityId) {
// TODO
}
@ -397,35 +480,6 @@ const UI = {
+ UI.renderRawData(activity.raw)
+ '</article>'
}
},
showTimeline: function(id, token, url) {
var timeline = new Timeline()
timeline.load(url, token, function(load_ok, failure_message) {
if (load_ok) {
var content = timeline.activities.map(
function(activity) {
if (UI.renderActivity[activity.type]) {
return UI.renderActivity[activity.type](activity)
} else {
return '<article class="activity">'
+ 'Other activity (' + activity.type + ').'
+ UI.renderRawActivity(activity)
+ '</article>'
}
}).join('')
content = content + '<section class="prev-next">'
if (timeline.prev) {
content = content + '<button onclick="UI.showTimeline(\'' + id + '\',' + (token ? '\'' + token + '\'' : 'undefined') + ',\'' + timeline.prev + '\')">Prev</button>'
}
if (timeline.next) {
content = content + '<button onclick="UI.showTimeline(\'' + id + '\',' + (token ? '\'' + token + '\'' : 'undefined') + ',\'' + timeline.next + '\')">Next</button>'
}
content = content + '</section>'
Elem(id).innerHTML = content
} else {
Elem(id + '-error').innerText = failure_message
}
})
}
*/
}

View File

@ -4,6 +4,7 @@ const {KnownActors} = require('./known-actors.js')
// Activity class
const Activity = function(raw_activity) {
this.raw = raw_activity
this.id = raw_activity.id
this.type = raw_activity.type
this.published = raw_activity.published ? new Date(raw_activity.published) : undefined
this.object = raw_activity.object

View File

@ -4,8 +4,19 @@ const {Activity} = require('./activity.js')
// Represent a collection of activities
var Timeline = function() {}
Timeline.prototype = {
// attributes
// List of activities
activities: [],
// Link to previous page
prev: undefined,
// Link to next page
next: undefined,
// Token used when loading -- for loading prev/next within the same context
token: undefined,
//
load: function(url, token, callback) {
var request = new XMLHttpRequest()
this.token = token
const request = new XMLHttpRequest()
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
var answer = JSON.parse(request.responseText)
@ -40,9 +51,9 @@ Timeline.prototype = {
},
parseActivities: function(raw_activities, callback) {
// Get the next activity
var raw_act = raw_activities.shift()
const raw_act = raw_activities.shift()
if (raw_act) {
var act = new Activity(raw_act)
const act = new Activity(raw_act)
act.loadActors(
function(load_ok, failure_message) {
if (load_ok) {