2021-05-24 13:48:22 +02:00
|
|
|
|
import {Actor} from './src/actor.js'
|
|
|
|
|
import {Timeline, KnownActivities} from './src/timeline.js'
|
|
|
|
|
import {Message} from './src/message.js'
|
|
|
|
|
import {ConnectedUser} from './src/connected-user.js'
|
2020-03-25 13:37:11 +01:00
|
|
|
|
|
2020-03-25 16:40:26 +01:00
|
|
|
|
// For access of elements
|
2020-03-27 17:08:59 +01:00
|
|
|
|
const Elem = function(id) {
|
2020-03-25 16:40:26 +01:00
|
|
|
|
return window.document.getElementById(id)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Icon list
|
|
|
|
|
const Icons = {
|
2020-04-01 18:06:47 +02:00
|
|
|
|
// Fallback icons
|
|
|
|
|
fallback: {
|
|
|
|
|
// Misc
|
|
|
|
|
'user': "img/unknown-user.svg",
|
|
|
|
|
'activity': "img/unknown-activity.svg",
|
|
|
|
|
},
|
|
|
|
|
// ActivityStream vocabulary: Activities
|
|
|
|
|
vocabulary_activity: {
|
|
|
|
|
'Accept': 'img/accept.svg',
|
|
|
|
|
'Add': 'img/add.svg',
|
|
|
|
|
'Announce': 'img/announce.svg',
|
2020-04-02 12:10:05 +02:00
|
|
|
|
'Arrive': 'img/arrive.svg',
|
2020-04-01 18:06:47 +02:00
|
|
|
|
'Block': 'img/block.svg',
|
|
|
|
|
'Create': 'img/create.svg',
|
|
|
|
|
'Delete': 'img/delete.svg',
|
|
|
|
|
'Dislike': 'img/dislike.svg',
|
|
|
|
|
'Flag': 'img/flag.svg',
|
|
|
|
|
'Follow': 'img/follow.svg',
|
|
|
|
|
'Ignore': 'img/ignore.svg',
|
2020-04-02 12:10:05 +02:00
|
|
|
|
'Invite': 'img/invite.svg',
|
|
|
|
|
'Join': 'img/join.svg',
|
|
|
|
|
'Leave': 'img/leave.svg',
|
2020-04-01 18:06:47 +02:00
|
|
|
|
'Like': 'img/like.svg',
|
2020-04-02 12:10:05 +02:00
|
|
|
|
'Listen': 'img/listen.svg',
|
|
|
|
|
'Move': 'img/move.svg',
|
|
|
|
|
'Offer': 'img/offer.svg',
|
2020-04-01 18:06:47 +02:00
|
|
|
|
'Question': 'img/question.svg',
|
|
|
|
|
'Reject': 'img/reject.svg',
|
2020-04-02 12:10:05 +02:00
|
|
|
|
'Read': 'img/read.svg',
|
2020-04-01 18:06:47 +02:00
|
|
|
|
'Remove': 'img/remove.svg',
|
|
|
|
|
'TentativeReject': 'img/reject.svg',
|
|
|
|
|
'TentativeAccept': 'img/accept.svg',
|
2020-04-02 12:10:05 +02:00
|
|
|
|
'Travel': 'img/travel.svg',
|
|
|
|
|
'Undo': 'img/undo.svg',
|
|
|
|
|
'Update': 'img/update.svg',
|
|
|
|
|
'View': 'img/view.svg'
|
2020-04-01 18:06:47 +02:00
|
|
|
|
},
|
|
|
|
|
// Get activity icon from its type
|
|
|
|
|
activity: function(type) {
|
|
|
|
|
return Icons.vocabulary_activity[type] ? Icons.vocabulary_activity[type] : Icons.fallback['activity']
|
|
|
|
|
}
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// To render elements that cannot be present in index.html from a model element
|
|
|
|
|
const Render = {
|
|
|
|
|
// Render an actor in audience fields context
|
|
|
|
|
audienceActor: function(actor) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
var display = '<section style="display:inline-block;">'
|
2020-03-25 13:37:11 +01:00
|
|
|
|
if (actor.valid) {
|
2020-04-04 18:34:45 +02:00
|
|
|
|
display = display + '<img src="' + actor.iconUrl(Icons.fallback['user']) + '" width="32" height="32" /> '
|
2020-03-27 17:08:59 +01:00
|
|
|
|
+ '<p style="display:inline-block;"><strong>' + actor.displayName() + '</strong> <br/>'
|
2020-04-04 18:34:45 +02:00
|
|
|
|
+ '<a href="' + actor.data.id + '">'
|
2020-03-27 17:08:59 +01:00
|
|
|
|
+ actor.address()
|
|
|
|
|
+ '</a></p>'
|
2020-03-25 13:37:11 +01:00
|
|
|
|
} else {
|
2020-04-01 18:06:47 +02:00
|
|
|
|
display = display + '<img src="' + Icons.fallback['user'] + '" width="32" height="32" /> '
|
2020-04-05 17:04:23 +02:00
|
|
|
|
+ '<p style="display:inline-block;">Unknown actor</p>'
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
display = display + '</section>'
|
|
|
|
|
return display
|
|
|
|
|
},
|
2020-03-31 17:27:05 +02:00
|
|
|
|
// Render an attachment
|
|
|
|
|
attachment: function(attachment) {
|
|
|
|
|
// If a string => link
|
|
|
|
|
var display = ''
|
|
|
|
|
if (typeof attachment === 'string') {
|
|
|
|
|
display = display + '<a href="' + attachment + '">Link to object</a>'
|
|
|
|
|
} else {
|
|
|
|
|
const type = attachment.type
|
|
|
|
|
const name = attachment.name
|
|
|
|
|
const url = attachment.url
|
|
|
|
|
const media_type = attachment.mediaType
|
|
|
|
|
// If the url is a string, display the element
|
|
|
|
|
if (typeof url === 'string') {
|
|
|
|
|
display = display + Render.attachmentFrom(type, name, media_type, url)
|
|
|
|
|
} else if (Array.isArray(url)) {
|
|
|
|
|
// Array of urls => unsupported
|
|
|
|
|
} else if (url.type && url.type === 'Link') {
|
|
|
|
|
// Object
|
|
|
|
|
display = display + Render.attachmentFrom(type, name, url.mediaType ? url.mediaType : media_type, url.href)
|
|
|
|
|
} else {
|
|
|
|
|
// Unsupported
|
|
|
|
|
}
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}
|
2020-03-31 17:27:05 +02:00
|
|
|
|
return display
|
|
|
|
|
},
|
|
|
|
|
attachmentFrom: function(type, name, media_type, url) {
|
|
|
|
|
// Show a link
|
|
|
|
|
var display = (type ? type : 'Document') + '<br/><a href="' + url + '">' + (name ? name : url) + '</a>'
|
|
|
|
|
// Show the attachment if it's an image, an audio, or a video
|
|
|
|
|
if (type && ((type === 'Image') || (type === 'Document' && media_type && media_type.startsWith('image/')))) {
|
|
|
|
|
display = display + '<br/><img src="' + url + '" width="300" ' + (name ? ('alt="' + name + '"') : '') + ' />'
|
|
|
|
|
} else if (type && ((type === 'Audio') || (type === 'Document' && media_type && media_type.startsWith('audio/')))) {
|
|
|
|
|
display = display + '<br/><audio controls preload="none" src="' + url + '">' + (name ? name : url) + '</audio>'
|
|
|
|
|
} else if (type && ((type === 'Video') || (type === 'Document' && media_type && media_type.startsWith('video/')))) {
|
|
|
|
|
display = display + '<br/><video controls preload="none" src="' + url + '" width="300" >' + (name ? name : url) + '</video>'
|
|
|
|
|
}
|
|
|
|
|
return display
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UI actions
|
|
|
|
|
const UI = {
|
|
|
|
|
// Attributes
|
|
|
|
|
composed_message: new Message(), // Message used in composition page
|
|
|
|
|
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
|
2020-03-30 10:34:40 +02:00
|
|
|
|
timeline: new Timeline(), // Collection of activities to display in the central column
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Contextual methods
|
|
|
|
|
refresh_context: {
|
|
|
|
|
'send-message': function() {
|
|
|
|
|
UI.updateNav('send-selector')
|
|
|
|
|
UI.showTimeline(undefined, undefined)
|
|
|
|
|
if (UI.is_connected) {
|
|
|
|
|
UI.showPage('send-message', undefined)
|
|
|
|
|
} else {
|
|
|
|
|
UI.showPage('select-user', undefined)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'my-inbox': function() {
|
|
|
|
|
UI.updateNav('inbox-selector')
|
|
|
|
|
if (UI.is_connected) {
|
2020-04-05 17:36:16 +02:00
|
|
|
|
UI.showTimeline(ConnectedUser.actor.data.inbox)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('show-profile', ConnectedUser.actor)
|
|
|
|
|
} else {
|
|
|
|
|
UI.showTimeline(undefined, undefined)
|
|
|
|
|
UI.showPage('select-user', undefined)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'my-outbox': function() {
|
|
|
|
|
UI.updateNav('outbox-selector')
|
|
|
|
|
if (UI.is_connected) {
|
2020-04-05 17:36:16 +02:00
|
|
|
|
UI.showTimeline(ConnectedUser.actor.data.outbox)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('show-profile', ConnectedUser.actor)
|
|
|
|
|
} else {
|
|
|
|
|
UI.showTimeline(undefined, undefined)
|
|
|
|
|
UI.showPage('select-user', undefined)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'my-profile': function() {
|
|
|
|
|
UI.updateNav('profile-selector')
|
|
|
|
|
UI.showTimeline(undefined, undefined)
|
|
|
|
|
if (UI.is_connected) {
|
|
|
|
|
UI.showPage('show-profile', ConnectedUser.actor)
|
|
|
|
|
} else {
|
|
|
|
|
UI.showPage('select-user', undefined)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
'other-profile': function() {
|
|
|
|
|
UI.updateNav(undefined)
|
2020-03-30 10:34:40 +02:00
|
|
|
|
UI.showPage('show-profile', UI.other_actor)
|
2020-04-04 18:34:45 +02:00
|
|
|
|
if (UI.other_actor.data.outbox) {
|
|
|
|
|
UI.showTimeline(UI.other_actor.data.outbox, undefined)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError('Actor does not have a public outbox.')
|
2020-03-30 10:34:40 +02:00
|
|
|
|
UI.showTimeline(undefined, undefined)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Page refresh methods
|
|
|
|
|
refresh_page: {
|
|
|
|
|
'select-user': function(_) {
|
2020-03-25 16:40:26 +01:00
|
|
|
|
Elem('connect-username').value = ''
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
'ask-password': function(_) {
|
2020-03-25 16:40:26 +01:00
|
|
|
|
Elem('connect-password').value = ''
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('ask-password-user-icon').innerHTML = '<img src="' + ConnectedUser.actor.iconUrl(Icons.fallback['user']) + '" width="32" height="32" />'
|
2020-03-27 17:08:59 +01:00
|
|
|
|
Elem('ask-password-user-display-name').innerText = ConnectedUser.actor.displayName()
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('ask-password-user-address').href = ConnectedUser.actor.data.id
|
2020-03-27 17:08:59 +01:00
|
|
|
|
Elem('ask-password-user-address').innerText = ConnectedUser.actor.address()
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
'show-profile': function(actor) {
|
|
|
|
|
// data contains the actor to display
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('profile-icon').innerHTML = '<img src="' + actor.iconUrl(Icons.fallback['user']) + '" width="96" height="96" />'
|
2020-03-27 17:08:59 +01:00
|
|
|
|
Elem('profile-display-name').innerText = actor.displayName()
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('profile-address').href = actor.data.id
|
2020-03-27 17:08:59 +01:00
|
|
|
|
Elem('profile-address').innerText = actor.address()
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('profile-type').innerText = actor.data.type
|
|
|
|
|
Elem('profile-summary').innerHTML = actor.data.summary
|
|
|
|
|
Elem('profile-code-source').innerText = JSON.stringify(actor.data._raw, null, 1)
|
2020-03-31 16:00:13 +02:00
|
|
|
|
// Controls only shown if the actor is the connected user
|
2020-04-04 18:34:45 +02:00
|
|
|
|
if (actor.data.id === ConnectedUser.actor.data.id) {
|
2020-03-31 16:00:13 +02:00
|
|
|
|
Elem('profile-controls-connected').style.display = 'block';
|
|
|
|
|
} else {
|
|
|
|
|
Elem('profile-controls-connected').style.display = 'none';
|
|
|
|
|
}
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-30 12:51:38 +02:00
|
|
|
|
'show-activity': function(activity) {
|
|
|
|
|
// data contains the activity to display
|
|
|
|
|
Elem('activity-type').innerText = activity.type
|
|
|
|
|
Elem('activity-published').innerText = activity.published ? activity.published.toLocaleString() : ''
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('activity-actor-icon').innerHTML = '<img src="' + activity.actor.iconUrl(Icons.fallback['user']) + '" width="48" height="48" />'
|
2020-03-30 12:51:38 +02:00
|
|
|
|
Elem('activity-actor-display-name').innerText = activity.actor.displayName()
|
|
|
|
|
Elem('activity-actor-address').innerText = activity.actor.address()
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('activity-actor-address').href = activity.actor.data.id
|
2020-03-30 12:51:38 +02:00
|
|
|
|
Elem('activity-to').innerHTML = activity.to.map(
|
|
|
|
|
function(element) {
|
|
|
|
|
return '<li class="actor-display">' + Render.audienceActor(element) + '</li>'
|
|
|
|
|
}).join('')
|
|
|
|
|
Elem('activity-cc').innerHTML = activity.cc.map(
|
|
|
|
|
function(element) {
|
|
|
|
|
return '<li class="actor-display">' + Render.audienceActor(element) + '</li>'
|
|
|
|
|
}).join('')
|
2020-04-05 17:04:23 +02:00
|
|
|
|
Elem('activity-code-source').innerText = JSON.stringify(activity.data._raw, null, 1)
|
2020-03-30 12:51:38 +02:00
|
|
|
|
// Object of activity
|
2020-03-30 17:51:02 +02:00
|
|
|
|
if (activity.object) {
|
|
|
|
|
Elem('activity-object').style.display = 'block'
|
|
|
|
|
Elem('activity-object-type').innerText = activity.object.type
|
|
|
|
|
Elem('activity-object-published').innerText = activity.object.published ? activity.object.published.toLocaleString() : ''
|
2020-04-04 18:34:45 +02:00
|
|
|
|
Elem('activity-object-actor-icon').innerHTML = '<img src="' + activity.object.actor.iconUrl(Icons.fallback['user']) + '" width="48" height="48" />'
|
2020-03-30 17:51:02 +02:00
|
|
|
|
Elem('activity-object-actor-display-name').innerText = activity.object.actor.displayName()
|
|
|
|
|
Elem('activity-object-actor-address').innerText = activity.object.actor.address()
|
2022-05-23 13:42:11 +02:00
|
|
|
|
if (activity.object.actor.data) {
|
|
|
|
|
Elem('activity-object-actor-address').href = activity.object.actor.data.id
|
|
|
|
|
}
|
2020-03-30 17:51:02 +02:00
|
|
|
|
Elem('activity-object-to').innerHTML = activity.object.to.map(
|
|
|
|
|
function(element) {
|
|
|
|
|
return '<li class="actor-display">' + Render.audienceActor(element) + '</li>'
|
|
|
|
|
}).join('')
|
|
|
|
|
Elem('activity-object-cc').innerHTML = activity.object.cc.map(
|
|
|
|
|
function(element) {
|
|
|
|
|
return '<li class="actor-display">' + Render.audienceActor(element) + '</li>'
|
|
|
|
|
}).join('')
|
2020-04-05 17:04:23 +02:00
|
|
|
|
Elem('activity-object-code-source').innerText = JSON.stringify(activity.object.data._raw, null, 1)
|
2020-04-02 12:12:32 +02:00
|
|
|
|
Elem('activity-object-name').innerText = activity.object.name
|
|
|
|
|
Elem('activity-object-summary').innerHTML = activity.object.summary
|
2020-03-30 17:51:02 +02:00
|
|
|
|
Elem('activity-object-content').innerHTML = activity.object.content
|
2020-03-31 16:00:13 +02:00
|
|
|
|
// If there are attachments on the object, display them
|
2020-03-31 17:27:05 +02:00
|
|
|
|
Elem('activity-object-attachments-number').innerText = activity.object.attachments.length
|
|
|
|
|
Elem('activity-object-attachments').innerHTML = activity.object.attachments.map(
|
|
|
|
|
function(element) {
|
|
|
|
|
return '<li class="attachment-display">' + Render.attachment(element) + '</li>'
|
|
|
|
|
}).join('')
|
2020-03-30 17:51:02 +02:00
|
|
|
|
} else {
|
|
|
|
|
// Hide the element
|
|
|
|
|
Elem('activity-object').style.display = 'none'
|
|
|
|
|
}
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
'send-message': function(_) {
|
|
|
|
|
Elem('send-message-to-recipient').value = ''
|
|
|
|
|
Elem('send-message-cc-recipient').value = ''
|
|
|
|
|
Elem('send-message-public-visibility').value = UI.composed_message.public_visibility
|
|
|
|
|
Elem('send-message-follower-visibility').value = UI.composed_message.follower_visibility
|
|
|
|
|
Elem('send-message-subject').value = UI.composed_message.subject
|
|
|
|
|
Elem('send-message-content').value = UI.composed_message.content
|
|
|
|
|
// TO/CC
|
|
|
|
|
Elem('send-message-to').innerHTML = UI.composed_message.to.map(
|
|
|
|
|
function(element) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
return '<li class="actor-display">'
|
|
|
|
|
+ Render.audienceActor(element)
|
2020-04-04 18:34:45 +02:00
|
|
|
|
+ ' <button style="vertical-align:top;" onclick="UI.removeToRecipient(\'' + element.data.id + '\')">×</button>'
|
2020-03-31 13:33:27 +02:00
|
|
|
|
+ '</li>'
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}).join('')
|
|
|
|
|
Elem('send-message-cc').innerHTML = UI.composed_message.cc.map(
|
|
|
|
|
function(element) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
return '<li class="actor-display">'
|
|
|
|
|
+ Render.audienceActor(element)
|
2020-04-04 18:34:45 +02:00
|
|
|
|
+ ' <button style="vertical-align:top;" onclick="UI.removeCcRecipient(\'' + element.data.id + '\')">×</button>'
|
2020-03-31 13:33:27 +02:00
|
|
|
|
+ '</li>'
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}).join('')
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Methods
|
|
|
|
|
// On load, auto-connect
|
2020-03-25 13:37:11 +01:00
|
|
|
|
checkConnection: function() {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Connect
|
2020-03-25 13:37:11 +01:00
|
|
|
|
ConnectedUser.loadFromLocalStorage(
|
2020-03-27 17:08:59 +01:00
|
|
|
|
function(load_ok, failure_message) {
|
|
|
|
|
UI.onConnectionChange(load_ok)
|
|
|
|
|
if (failure_message) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError(failure_message)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
// On connected, show the right page
|
|
|
|
|
onConnectionChange: function(connected) {
|
|
|
|
|
UI.is_connected = connected
|
|
|
|
|
UI.refresh_context[UI.current_context]()
|
|
|
|
|
},
|
|
|
|
|
// Display content errors
|
2020-03-31 13:33:27 +02:00
|
|
|
|
displayError: function(message) {
|
|
|
|
|
Elem('error').style.display = 'block'
|
|
|
|
|
Elem('content-error').innerText = message
|
2020-03-27 17:08:59 +01:00
|
|
|
|
},
|
|
|
|
|
// Clear error messages
|
|
|
|
|
clearError: function() {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
Elem('error').style.display = 'none'
|
2020-03-27 17:08:59 +01:00
|
|
|
|
Elem('content-error').innerText = ''
|
|
|
|
|
},
|
|
|
|
|
// Show a page
|
|
|
|
|
showPage: function(page, data) {
|
|
|
|
|
// Clear errors
|
|
|
|
|
UI.clearError()
|
|
|
|
|
// Hide all other pages
|
|
|
|
|
for (const p in UI.refresh_page) {
|
|
|
|
|
Elem(p).style.display = 'none'
|
|
|
|
|
}
|
|
|
|
|
// Show the page
|
|
|
|
|
Elem(page).style.display = 'block'
|
|
|
|
|
// Refresh
|
|
|
|
|
UI.refresh_page[page](data)
|
|
|
|
|
},
|
|
|
|
|
// Show the timeline
|
2020-04-05 17:36:16 +02:00
|
|
|
|
showTimeline: function(url) {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
if (url) {
|
|
|
|
|
Elem('timeline').style.display = 'block'
|
|
|
|
|
Elem('timeline-data').innerHTML = 'Loading collection...'
|
2020-03-31 13:33:27 +02:00
|
|
|
|
Elem('timeline-prev-top').disabled = true
|
|
|
|
|
Elem('timeline-next-top').disabled = true
|
2020-03-30 10:34:40 +02:00
|
|
|
|
UI.timeline = new Timeline()
|
|
|
|
|
UI.timeline.load(
|
|
|
|
|
url,
|
|
|
|
|
function(load_ok, failure_message) {
|
|
|
|
|
if (load_ok) {
|
|
|
|
|
Elem('timeline-data').innerHTML = UI.timeline.activities.map(function(activity) {
|
2020-03-30 17:51:02 +02:00
|
|
|
|
return '<section class="timeline-activity" onclick="UI.showActivity(\'' + activity.id + '\');">'
|
2020-04-01 18:06:47 +02:00
|
|
|
|
+ '<img src="' + Icons.activity(activity.type) + '" width="32" height="32"> '
|
|
|
|
|
+ '<p style="display:inline-block;">'
|
|
|
|
|
+ '<strong>' + activity.type
|
|
|
|
|
+ ((activity.object && activity.object.type) ? ' (' + activity.object.type + ')' : '')
|
|
|
|
|
+ '</strong><br/>'
|
|
|
|
|
+ activity.actor.displayName() + '</p></section>'
|
2020-03-30 10:34:40 +02:00
|
|
|
|
}).join('')
|
|
|
|
|
if (UI.timeline.prev) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
Elem('timeline-prev-top').disabled = false
|
2020-03-30 10:34:40 +02:00
|
|
|
|
}
|
|
|
|
|
if (UI.timeline.next) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
Elem('timeline-next-top').disabled = false
|
2020-03-30 10:34:40 +02:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError(failure_message)
|
2020-03-30 10:34:40 +02:00
|
|
|
|
Elem('timeline-data').innerHTML = ''
|
|
|
|
|
}
|
2020-03-30 17:51:02 +02:00
|
|
|
|
})
|
2020-03-27 17:08:59 +01:00
|
|
|
|
} else {
|
|
|
|
|
Elem('timeline').style.display = 'none'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// Update the nav
|
|
|
|
|
updateNav: function(selected) {
|
|
|
|
|
// Unselect all options
|
|
|
|
|
['send-selector', 'inbox-selector', 'outbox-selector', 'profile-selector'].map(x => Elem(x).checked = false)
|
|
|
|
|
if (selected) {
|
|
|
|
|
Elem(selected).checked = true
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// Change context
|
|
|
|
|
setContext: function(ctx) {
|
|
|
|
|
UI.current_context = ctx
|
|
|
|
|
UI.refresh_context[UI.current_context]()
|
|
|
|
|
},
|
|
|
|
|
// Lookup actor
|
|
|
|
|
lookupActor: function() {
|
|
|
|
|
// Find the actor and change to the 'other-profile' context
|
|
|
|
|
UI.other_actor = new Actor()
|
|
|
|
|
UI.other_actor.loadFromNameServerAddress(
|
|
|
|
|
Elem('lookup-actor').value,
|
2020-03-25 13:37:11 +01:00
|
|
|
|
function(load_ok, failure_message) {
|
|
|
|
|
if (load_ok) {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.setContext('other-profile')
|
2020-03-25 13:37:11 +01:00
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError('Unable to find user (' + failure_message + ')')
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Action on the select-user page
|
2020-03-25 13:37:11 +01:00
|
|
|
|
selectUser: function() {
|
|
|
|
|
// Load the actor and go to the ask-password page
|
2020-03-26 12:50:22 +01:00
|
|
|
|
ConnectedUser.actor.loadFromNameServerAddress(
|
|
|
|
|
Elem('connect-username').value,
|
2020-03-25 13:37:11 +01:00
|
|
|
|
function(load_ok, failure_message) {
|
|
|
|
|
if (load_ok) {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('ask-password', undefined)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError(failure_message)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Action on the ask-password page
|
2020-03-25 13:37:11 +01:00
|
|
|
|
connectUser: function() {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Connect the user
|
2020-03-25 13:37:11 +01:00
|
|
|
|
ConnectedUser.connect(
|
2020-03-25 16:40:26 +01:00
|
|
|
|
Elem('connect-password').value,
|
2020-03-25 13:37:11 +01:00
|
|
|
|
function(load_ok, failure_message) {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.onConnectionChange(load_ok)
|
|
|
|
|
if (failure_message) {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError(failure_message)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
2020-03-31 16:00:13 +02:00
|
|
|
|
// Action on the profile page
|
|
|
|
|
disconnectUser: function() {
|
|
|
|
|
// Disconnect the user
|
|
|
|
|
ConnectedUser.disconnect()
|
|
|
|
|
UI.onConnectionChange(false)
|
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Action on the send page
|
|
|
|
|
// Update visibility
|
2020-03-25 13:37:11 +01:00
|
|
|
|
updateSendVisibility: function() {
|
2020-03-25 16:40:26 +01:00
|
|
|
|
UI.composed_message.setVisibility(Elem('send-message-public-visibility').value, Elem('send-message-follower-visibility').value)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Add in To
|
2020-03-25 13:37:11 +01:00
|
|
|
|
addToRecipient: function() {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
const actor = new Actor()
|
2020-03-26 12:50:22 +01:00
|
|
|
|
actor.loadFromNameServerAddress(
|
|
|
|
|
Elem('send-message-to-recipient').value,
|
2020-03-25 13:37:11 +01:00
|
|
|
|
function(load_ok, failure_message) {
|
|
|
|
|
if (load_ok) {
|
|
|
|
|
UI.composed_message.addToRecipient(actor)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('send-message', undefined)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError('Unable to find user (' + failure_message + ')')
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Add in Cc
|
2020-03-25 13:37:11 +01:00
|
|
|
|
addCcRecipient: function() {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
const actor = new Actor()
|
2020-03-26 12:50:22 +01:00
|
|
|
|
actor.loadFromNameServerAddress(
|
2020-04-05 18:02:23 +02:00
|
|
|
|
Elem('send-message-cc-recipient').value,
|
2020-03-25 13:37:11 +01:00
|
|
|
|
function(load_ok, failure_message) {
|
|
|
|
|
if (load_ok) {
|
|
|
|
|
UI.composed_message.addCcRecipient(actor)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('send-message', undefined)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError('Unable to find user (' + failure_message + ')')
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Remove from To
|
2020-03-25 13:37:11 +01:00
|
|
|
|
removeToRecipient: function(url_profile) {
|
|
|
|
|
// Don't fetch the actor, only set the profile url used in removal
|
2020-04-05 18:02:23 +02:00
|
|
|
|
const actor = {data: {id: url_profile}}
|
2020-03-25 13:37:11 +01:00
|
|
|
|
UI.composed_message.removeToRecipient(actor)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('send-message', undefined)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Remove from Cc
|
2020-03-25 13:37:11 +01:00
|
|
|
|
removeCcRecipient: function(url_profile) {
|
2020-03-27 17:08:59 +01:00
|
|
|
|
// Don't fetch the actor, only set the profile url used in removal
|
2020-04-05 18:02:23 +02:00
|
|
|
|
const actor = {data: {id: url_profile}}
|
2020-03-25 13:37:11 +01:00
|
|
|
|
UI.composed_message.removeCcRecipient(actor)
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('send-message', undefined)
|
|
|
|
|
},
|
|
|
|
|
// Update message content
|
|
|
|
|
updateSendContent: function() {
|
|
|
|
|
UI.composed_message.setContent(Elem('send-message-subject').value, Elem('send-message-content').value)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
},
|
|
|
|
|
// Send message
|
|
|
|
|
sendMessage: function() {
|
|
|
|
|
UI.composed_message.send(
|
|
|
|
|
function(is_ok, failure_message) {
|
|
|
|
|
if (is_ok) {
|
2020-04-05 18:02:23 +02:00
|
|
|
|
// Clear message
|
|
|
|
|
UI.composed_message = new Message()
|
2020-03-27 17:08:59 +01:00
|
|
|
|
UI.showPage('send-message', undefined)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
} else {
|
2020-03-31 13:33:27 +02:00
|
|
|
|
UI.displayError('Error when sending message: ' + failure_message)
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
})
|
2020-03-30 10:34:40 +02:00
|
|
|
|
},
|
|
|
|
|
// Timeline navigation
|
|
|
|
|
nextTimeline: function() {
|
|
|
|
|
if (UI.timeline.next) {
|
2020-04-05 17:36:16 +02:00
|
|
|
|
UI.showTimeline(UI.timeline.next)
|
2020-03-30 10:34:40 +02:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
prevTimeline: function() {
|
|
|
|
|
if (UI.timeline.prev) {
|
2020-04-05 17:36:16 +02:00
|
|
|
|
UI.showTimeline(UI.timeline.prev)
|
2020-03-30 10:34:40 +02:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// Show contents of activities
|
|
|
|
|
showActivity: function(activityId) {
|
2020-04-05 17:04:23 +02:00
|
|
|
|
const act = KnownActivities.get(activityId)
|
|
|
|
|
act.loadAll(function (load_ok, failure_message) {
|
|
|
|
|
if (load_ok) {
|
|
|
|
|
UI.showPage('show-activity', act)
|
|
|
|
|
}
|
|
|
|
|
if (failure_message) {
|
|
|
|
|
UI.displayError(failure_message)
|
|
|
|
|
}
|
|
|
|
|
})
|
2020-03-25 13:37:11 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-05-24 13:48:22 +02:00
|
|
|
|
|
|
|
|
|
export {UI}
|