Basic first setup (JS and CSS - 2 themes)

This commit is contained in:
シモン 2017-05-01 16:40:19 +09:00
commit 42efc47e2f
3 changed files with 343 additions and 0 deletions

53
README.md Normal file
View file

@ -0,0 +1,53 @@
# Mastodon.widget
The idea of this little script is to allow users to display their Mastodon timeline on their blog/website.
## Requirements
- jQuery
- access token from the mastodon instance you want to display the timeline from
To help you create a token, we'll soon provide a page on our website that will guide you through the requiered steps.
## Installation
1) Download the required files (only one JS and one CSS).
2) Simply paste the code bellow in you website:
<link rel="stylesheet" href="mastodon.widget.css">
<script type="text/javascript" src="mastodon.widget.js"></script>
<script>
$(document).ready(function() {
// jQUERY is required!
var mapi = new MastodonApi({
target_selector : '#myTimeline'
,instance_uri : '[MASTODON INSTANCE]'
,access_token : '[ACCESS TOKEN]'
,account_id : '[ACCOUNT ID]'
// optional parameters
//,toots_limit : 5
});
});
</script>
In the sample above, you have to replace the folowing:
- [MASTODON INSTANCE] => i.e : https://mastodon.technology
- [ACCESS TOKEN] => token you created for your app and linked with your Mastodon instance account
- [ACCOUNT ID] => your user ID on Mastodon instance
3) Add a container for your timeline where you want in the body of your website:
<div id="myTimeline" class="mastodon-timeline mastodon-timeline-dark"></div>
## Customization
You have the choice between 2 basic themes:
- mastodon-timeline-light
- mastodon-timeline-dark
Or you can create your own. Please have a look in the CSS file for more details.

136
mastodon.widget.css Normal file
View file

@ -0,0 +1,136 @@
/* main container >>> */
.mastodon-timeline {
box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
font-family: sans-serif;
margin-bottom: 1em;
}
.mt-header,
.mt-footer {
padding: 10px 10px;
}
.mastodon-timeline a:link,
.mastodon-timeline a:active,
.mastodon-timeline a {
text-decoration: none;
font-weight: normal;
}
.mt-header {
font-weight: bold;
border-bottom: 1px solid purple;
}
.mt-header h4 {
display: inline-block;
}
.mt-body {
height: 250px;
overflow-y: auto;
}
.mt-loading {
padding: 10px;
text-align: center;
}
.mt-footer {
text-align: center;
}
/* toots -messages */
.mt-toot {
margin: 5px;
padding: 5px 5px 5px 65px;
position: relative;
min-height: 60px;
}
.mt-footer,
.mt-toot:nth-child(n+2) {
border-top: 1px solid purple;
}
.mt-toot p:last-child {
margin-bottom: 0;
}
.mt-date {
text-align: right;
}
.mt-avatar {
position: absolute;
top: 5px;
left: 5px;
/*margin: 0 10px 5px 0;*/
width: 50px;
height: 50px;
border-radius: 5px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
}
/* <<< */
/* light theme >>> */
.mastodon-timeline-light {
background: #fafafa;
color: #555;
}
.mastodon-timeline-light .mt-footer,
.mastodon-timeline-light .mt-header {
background: #eee;
}
.mastodon-timeline-light a:link,
.mastodon-timeline-light a:active,
.mastodon-timeline-light a {
color: #26afff;
}
.mastodon-timeline-light .mt-header {
border-bottom-color: lightgrey;
}
.mastodon-timeline-light .mt-footer,
.mastodon-timeline-light .mt-toot:nth-child(n+2) {
border-top-color: lightgrey;
}
.mastodon-timeline-light .mt-date a {
color: lightgrey;
}
/* <<< */
/* dark theme >>> */
.mastodon-timeline-dark {
background: #393f4f;
color: white;
}
.mastodon-timeline-dark .mt-footer,
.mastodon-timeline-dark .mt-header {
background: #313543;
}
.mastodon-timeline-dark a:link,
.mastodon-timeline-dark a:active,
.mastodon-timeline-dark a {
color: #2b90d9;
}
.mastodon-timeline-dark .mt-header {
border-bottom-color: #606984;
}
.mastodon-timeline-dark .mt-footer,
.mastodon-timeline-dark .mt-toot:nth-child(n+2) {
border-top-color: #606984;
}
.mastodon-timeline-dark .mt-date a {
color: #606984;
}
/* <<< */

154
mastodon.widget.js Normal file
View file

@ -0,0 +1,154 @@
/**
* Mastodon User Timeline Widget
*
* @author Azet <https://azet.jp>
* @param object params_
* instance_uri : the instance to fetch messages from
* access_token : widget's application access token (can be generated from http://azet.jp/mastodon-usertimeline-widget/)
* account_id : user account id to fetch messages of
* target_selector : HTML node selector (jquery/css style)
*/
var MastodonApi = function(params_) {
// endpoint access settings
this.INSTANCE_URI = params_.instance_uri;
this.ACCESS_TOKEN = params_.access_token;
this.ACCOUNT_ID = params_.account_id;
// optional parameters
this.toots_limit = params_.toots_limit || 20;
// display target element
this.widget = $(params_.target_selector);
// build the basic widget
this.makeWidget();
this.listStatuses();
}
/**
* build timeline widget
*/
MastodonApi.prototype.makeWidget = function() {
this.widget.addClass('mastodon-timeline');
this.widget.append($('<div class="mt-header"><h4>Toots</h4> by <span class="user-link"></span></div>'));
this.widget.append($('<div class="mt-body"><div class="mt-loading">loading...</div></div>'));
this.widget.append($('<div class="mt-footer"></div>'));
};
/**
* listing function
*/
MastodonApi.prototype.listStatuses = function() {
var mapi = this;
// get request
$.ajax({
url: this.INSTANCE_URI+'/api/v1/accounts/'+this.ACCOUNT_ID+'/statuses'
,headers: {
Authorization : 'Bearer '+this.ACCESS_TOKEN
}
,method : 'GET'
,dataType: 'json'
,data : {
limit : this.toots_limit
}
,success: function(data_) {
// clear the loading message
$('.mt-body', mapi.widget).html("");
//console.log( data_ );
// add posts
for(var i in data_) {
if(i==0) {
// update user link only at first post
var account = data_[i].account;
setHeaderUserLink.call(mapi, account);
setFooterLink.call(mapi, account);
}
appendStatus.call(mapi, data_[i]);
}
// fix content link target
$('a', this.widget).attr('target', '_blank');
}
});
/**
* add user link
* @param object account_
*/
var setHeaderUserLink = function(account_) {
// set user name and link
$('.user-link', this.widget).append("<a href='"+account_.url+"'>@"+account_.username+"</a>");
};
/**
* add user link
* @param object account_
*/
var setFooterLink = function(account_) {
var domain = this.INSTANCE_URI.replace(/https?:\/\//, '');
$('.mt-footer', this.widget).append("View on <a href='"+account_.url+"'>"+domain+"</a>");
};
/**
* inner function to add each message in container
* @param object status_
*/
var appendStatus = function(status_) {
//console.log( status_ );
var content = $(status_.content);
var date = prepareDateDisplay(status_.created_at);
var timestamp = $("<div class='mt-date'><a href='"+status_.url+"'>" + date + "</a></div>");
// status container
var toot = $("<div class='mt-toot clearfix'></div>");
// avatar
var avatar = $("<div class='mt-avatar'></div>");
avatar.css({
'background' : "white url('"+status_.account.avatar+"') 50% 50% no-repeat"
,'background-size' : 'contain'
});
// user name and url
var user = $("<div class='mt-user'><a href='"+status_.account.url+"'>"+status_.account.username+"</a></div>");
// add to HTML
toot.append( avatar );
toot.append( user );
toot.append( timestamp );
toot.append( content );
$('.mt-body', this.widget).append(toot);
};
/**
* display toot time
*
* @author Azet
* @param StringDate date_ (standard time format)
* @return String
*/
var prepareDateDisplay = function(date_) {
var displayTime = "";
//var now = new Date();
var date = new Date( date_ );
displayTime = date.getFullYear()
+"/"+(date.getMonth()+1)
+"/"+date.getDate()
+" "+date.getHours()
+":"+("0"+date.getMinutes()).replace(/0(\d{2})/, "$1")
;
return displayTime;
}
};