TheDesk
This commit is contained in:
6
js/common/about.js
Normal file
6
js/common/about.js
Normal file
@@ -0,0 +1,6 @@
|
||||
//このソフトについて
|
||||
function about() {
|
||||
var electron = require("electron");
|
||||
var ipc = electron.ipcRenderer;
|
||||
ipc.send('about', 'go');
|
||||
}
|
7
js/common/hammer.min.js
vendored
Normal file
7
js/common/hammer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
js/common/jquery.js
vendored
Normal file
4
js/common/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
101
js/common/keyshortcut.js
Normal file
101
js/common/keyshortcut.js
Normal file
@@ -0,0 +1,101 @@
|
||||
$(function($) {
|
||||
//キーボードショートカット
|
||||
$(window).keydown(function(e) {
|
||||
var hasFocus = $('input').is(':focus');
|
||||
var hasFocus2 = $('textarea').is(':focus');
|
||||
//Ctrl+Enter:投稿
|
||||
if (event.ctrlKey) {
|
||||
if (e.keyCode === 13) {
|
||||
post();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//input/textareaにフォーカスなし時
|
||||
if (!hasFocus && !hasFocus2) {
|
||||
//X:開閉
|
||||
if (e.keyCode === 88) {
|
||||
if ($("#post-box").hasClass("hidenbox")) {
|
||||
show();
|
||||
$('textarea').focus();
|
||||
} else {
|
||||
hide();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//N:新トゥート
|
||||
if (e.keyCode === 78) {
|
||||
if ($("#post-box").hasClass("hidenbox")) {
|
||||
show();
|
||||
}
|
||||
$('textarea').focus();
|
||||
return false;
|
||||
}
|
||||
//E:拡張On/Off
|
||||
if (e.keyCode === 69) {
|
||||
zoomBox();
|
||||
return false;
|
||||
}
|
||||
//Ctrl+Space:読み込み
|
||||
if (event.ctrlKey) {
|
||||
if (e.keyCode === 32) {
|
||||
parseColumn();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//Sift+C:全消し
|
||||
if (event.shiftKey) {
|
||||
if (e.keyCode === 67) {
|
||||
clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//textareaフォーカス時
|
||||
if (hasFocus2) {
|
||||
if (event.ctrlKey) {
|
||||
//Ctrl+B:太字
|
||||
if (e.keyCode === 66) {
|
||||
tagsel('b');
|
||||
return false;
|
||||
}
|
||||
//Ctrl+I:斜字
|
||||
if (e.keyCode === 73) {
|
||||
tagsel('i');
|
||||
return false;
|
||||
}
|
||||
//Ctrl+U:下線
|
||||
if (e.keyCode === 85) {
|
||||
tagsel('u');
|
||||
return false;
|
||||
}
|
||||
//Ctrl+S:取り消し線
|
||||
if (e.keyCode === 83) {
|
||||
tagsel('s');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//F5:スーパーリロード?
|
||||
if (e.keyCode === 116) {
|
||||
location.href = "index.html"
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//37,39
|
||||
if (e.keyCode === 37) {
|
||||
if($("#imagemodal").hasClass("open")){
|
||||
imgCont('prev');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (e.keyCode === 39) {
|
||||
if($("#imagemodal").hasClass("open")){
|
||||
imgCont('next');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
//クリアボタン
|
||||
$("#clear").click(function() {
|
||||
clear();
|
||||
});
|
||||
});
|
10021
js/common/materialize.js
vendored
Normal file
10021
js/common/materialize.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
6
js/common/materialize.min.js
vendored
Normal file
6
js/common/materialize.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
18
js/common/modal.js
Normal file
18
js/common/modal.js
Normal file
@@ -0,0 +1,18 @@
|
||||
//モーダル・ドロップダウンの各種設定
|
||||
$(document).ready(function(){
|
||||
// the "href" attribute of the modal trigger must specify the modal ID that wants to be triggered
|
||||
$('.modal').modal();
|
||||
$('.dropdown-button').dropdown({
|
||||
inDuration: 300,
|
||||
outDuration: 225,
|
||||
constrainWidth: false, // Does not change width of dropdown to that of the activator
|
||||
hover: true, // Activate on hover
|
||||
gutter: 0, // Spacing from edge
|
||||
belowOrigin: false, // Displays dropdown below the button
|
||||
alignment: 'left', // Displays dropdown with edge aligned to the left of button
|
||||
stopPropagation: false // Stops event propagation
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
|
232
js/common/time.js
Normal file
232
js/common/time.js
Normal file
@@ -0,0 +1,232 @@
|
||||
/**
|
||||
* Timeago is a jQuery plugin that makes it easy to support automatically
|
||||
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
|
||||
*
|
||||
* @name timeago
|
||||
* @version 1.6.1
|
||||
* @requires jQuery v1.2.3+
|
||||
* @author Ryan McGeary
|
||||
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
|
||||
*
|
||||
* For usage and examples, visit:
|
||||
* http://timeago.yarp.com/
|
||||
*
|
||||
* Copyright (c) 2008-2017, Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
|
||||
*/
|
||||
|
||||
(function (factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && typeof module.exports === 'object') {
|
||||
factory(require('jquery'));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
$.timeago = function(timestamp) {
|
||||
if (timestamp instanceof Date) {
|
||||
return inWords(timestamp);
|
||||
} else if (typeof timestamp === "string") {
|
||||
return inWords($.timeago.parse(timestamp));
|
||||
} else if (typeof timestamp === "number") {
|
||||
return inWords(new Date(timestamp));
|
||||
} else {
|
||||
return inWords($.timeago.datetime(timestamp));
|
||||
}
|
||||
};
|
||||
var $t = $.timeago;
|
||||
|
||||
$.extend($.timeago, {
|
||||
settings: {
|
||||
refreshMillis: 60000,
|
||||
allowPast: true,
|
||||
allowFuture: false,
|
||||
localeTitle: false,
|
||||
cutoff: 0,
|
||||
autoDispose: true,
|
||||
strings: {
|
||||
prefixAgo: null,
|
||||
prefixFromNow: "今から",
|
||||
suffixAgo: "",
|
||||
suffixFromNow: "",
|
||||
inPast: '',
|
||||
seconds: "%d秒前",
|
||||
minute: "1分前",
|
||||
minutes: "%d分前",
|
||||
hour: "1時間前",
|
||||
hours: "%d時間前",
|
||||
day: "昨日",
|
||||
days: "%d日前",
|
||||
month: "昨月",
|
||||
months: "%dヶ月前",
|
||||
year: "去年",
|
||||
years: "%d年前",
|
||||
wordSeparator: " ",
|
||||
numbers: []
|
||||
}
|
||||
},
|
||||
|
||||
inWords: function(distanceMillis) {
|
||||
if (!this.settings.allowPast && ! this.settings.allowFuture) {
|
||||
throw 'timeago allowPast and allowFuture settings can not both be set to false.';
|
||||
}
|
||||
|
||||
var $l = this.settings.strings;
|
||||
var prefix = $l.prefixAgo;
|
||||
var suffix = $l.suffixAgo;
|
||||
if (this.settings.allowFuture) {
|
||||
if (distanceMillis < 0) {
|
||||
prefix = $l.prefixFromNow;
|
||||
suffix = $l.suffixFromNow;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.settings.allowPast && distanceMillis >= 0) {
|
||||
return this.settings.strings.inPast;
|
||||
}
|
||||
|
||||
var seconds = Math.abs(distanceMillis) / 1000;
|
||||
var minutes = seconds / 60;
|
||||
var hours = minutes / 60;
|
||||
var days = hours / 24;
|
||||
var years = days / 365;
|
||||
|
||||
function substitute(stringOrFunction, number) {
|
||||
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
|
||||
var value = ($l.numbers && $l.numbers[number]) || number;
|
||||
return string.replace(/%d/i, value);
|
||||
}
|
||||
|
||||
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
|
||||
seconds < 90 && substitute($l.minute, 1) ||
|
||||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
|
||||
minutes < 90 && substitute($l.hour, 1) ||
|
||||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
|
||||
hours < 42 && substitute($l.day, 1) ||
|
||||
days < 30 && substitute($l.days, Math.round(days)) ||
|
||||
days < 45 && substitute($l.month, 1) ||
|
||||
days < 365 && substitute($l.months, Math.round(days / 30)) ||
|
||||
years < 1.5 && substitute($l.year, 1) ||
|
||||
substitute($l.years, Math.round(years));
|
||||
|
||||
var separator = $l.wordSeparator || "";
|
||||
if ($l.wordSeparator === undefined) { separator = " "; }
|
||||
return $.trim([prefix, words, suffix].join(separator));
|
||||
},
|
||||
|
||||
parse: function(iso8601) {
|
||||
var s = $.trim(iso8601);
|
||||
s = s.replace(/\.\d+/,""); // remove milliseconds
|
||||
s = s.replace(/-/,"/").replace(/-/,"/");
|
||||
s = s.replace(/T/," ").replace(/Z/," UTC");
|
||||
s = s.replace(/([\+\-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
|
||||
s = s.replace(/([\+\-]\d\d)$/," $100"); // +09 -> +0900
|
||||
return new Date(s);
|
||||
},
|
||||
datetime: function(elem) {
|
||||
var iso8601 = $t.isTime(elem) ? $(elem).attr("datetime") : $(elem).attr("title");
|
||||
return $t.parse(iso8601);
|
||||
},
|
||||
isTime: function(elem) {
|
||||
// jQuery's `is()` doesn't play well with HTML5 in IE
|
||||
return $(elem).get(0).tagName.toLowerCase() === "time"; // $(elem).is("time");
|
||||
}
|
||||
});
|
||||
|
||||
// functions that can be called via $(el).timeago('action')
|
||||
// init is default when no action is given
|
||||
// functions are called with context of a single element
|
||||
var functions = {
|
||||
init: function() {
|
||||
functions.dispose.call(this);
|
||||
var refresh_el = $.proxy(refresh, this);
|
||||
refresh_el();
|
||||
var $s = $t.settings;
|
||||
if ($s.refreshMillis > 0) {
|
||||
this._timeagoInterval = setInterval(refresh_el, $s.refreshMillis);
|
||||
}
|
||||
},
|
||||
update: function(timestamp) {
|
||||
var date = (timestamp instanceof Date) ? timestamp : $t.parse(timestamp);
|
||||
$(this).data('timeago', { datetime: date });
|
||||
if ($t.settings.localeTitle) {
|
||||
$(this).attr("title", date.toLocaleString());
|
||||
}
|
||||
refresh.apply(this);
|
||||
},
|
||||
updateFromDOM: function() {
|
||||
$(this).data('timeago', { datetime: $t.parse( $t.isTime(this) ? $(this).attr("datetime") : $(this).attr("title") ) });
|
||||
refresh.apply(this);
|
||||
},
|
||||
dispose: function () {
|
||||
if (this._timeagoInterval) {
|
||||
window.clearInterval(this._timeagoInterval);
|
||||
this._timeagoInterval = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.timeago = function(action, options) {
|
||||
var fn = action ? functions[action] : functions.init;
|
||||
if (!fn) {
|
||||
throw new Error("Unknown function name '"+ action +"' for timeago");
|
||||
}
|
||||
// each over objects here and call the requested function
|
||||
this.each(function() {
|
||||
fn.call(this, options);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
function refresh() {
|
||||
var $s = $t.settings;
|
||||
|
||||
//check if it's still visible
|
||||
if ($s.autoDispose && !$.contains(document.documentElement,this)) {
|
||||
//stop if it has been removed
|
||||
$(this).timeago("dispose");
|
||||
return this;
|
||||
}
|
||||
|
||||
var data = prepareData(this);
|
||||
|
||||
if (!isNaN(data.datetime)) {
|
||||
if ( $s.cutoff === 0 || Math.abs(distance(data.datetime)) < $s.cutoff) {
|
||||
$(this).text(inWords(data.datetime));
|
||||
} else {
|
||||
if ($(this).attr('title').length > 0) {
|
||||
$(this).text($(this).attr('title'));
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
function prepareData(element) {
|
||||
element = $(element);
|
||||
if (!element.data("timeago")) {
|
||||
element.data("timeago", { datetime: $t.datetime(element) });
|
||||
var text = $.trim(element.text());
|
||||
if ($t.settings.localeTitle) {
|
||||
element.attr("title", element.data('timeago').datetime.toLocaleString());
|
||||
} else if (text.length > 0 && !($t.isTime(element) && element.attr("title"))) {
|
||||
element.attr("title", text);
|
||||
}
|
||||
}
|
||||
return element.data("timeago");
|
||||
}
|
||||
|
||||
function inWords(date) {
|
||||
return $t.inWords(distance(date));
|
||||
}
|
||||
|
||||
function distance(date) {
|
||||
return (new Date().getTime() - date.getTime());
|
||||
}
|
||||
|
||||
// fix for IE6 suckage
|
||||
document.createElement("abbr");
|
||||
document.createElement("time");
|
||||
}));
|
25
js/common/version.js
Normal file
25
js/common/version.js
Normal file
@@ -0,0 +1,25 @@
|
||||
//バージョンチェッカー
|
||||
function verck(ver) {
|
||||
localStorage.setItem("ver", ver);
|
||||
var start = "https://desk.cutls.com/ver.json";
|
||||
fetch(start, {
|
||||
method: 'GET'
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(mess) {
|
||||
console.log(mess);
|
||||
if (mess) {
|
||||
if (mess.desk == ver) {
|
||||
todo("お使いのバージョン" + mess.desk + "は最新です。");
|
||||
//betaならアプデチェックしない
|
||||
} else if (ver != "beta") {
|
||||
var electron = require("electron");
|
||||
var ipc = electron.ipcRenderer;
|
||||
ipc.send('update', "true");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
247
js/login/login.js
Normal file
247
js/login/login.js
Normal file
@@ -0,0 +1,247 @@
|
||||
/*ログイン処理・認証までのJS*/
|
||||
//最初に読むやつ
|
||||
function ck() {
|
||||
var domain = localStorage.getItem("domain_0");
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (at) {
|
||||
ckdb();
|
||||
$("#tl").show();
|
||||
parseColumn();
|
||||
multi();
|
||||
} else {
|
||||
$("#masara").show();
|
||||
console.log("Please Login");
|
||||
support();
|
||||
}
|
||||
}
|
||||
ck();
|
||||
|
||||
//ログインポップアップ
|
||||
function login(url) {
|
||||
var start = "https://" + url + "/api/v1/apps";
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
scopes: 'read write follow',
|
||||
client_name: "TheDesk(PC)",
|
||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||
website: "https://desk.cutls.com"
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var auth = "https://" + url + "/oauth/authorize?client_id=" + json[
|
||||
"client_id"] + "&client_secret=" + json["client_secret"] +
|
||||
"&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=read+write+follow";
|
||||
localStorage.setItem("domain_" + acct_id, url);
|
||||
localStorage.setItem("client_id", json["client_id"]);
|
||||
localStorage.setItem("client_secret", json["client_secret"]);
|
||||
$("#auth").show();
|
||||
$("#masara").hide();
|
||||
window.open(auth);
|
||||
});
|
||||
}
|
||||
|
||||
//テキストボックスにURL入れた
|
||||
function instance() {
|
||||
var url = $("#url").val();
|
||||
login(url);
|
||||
}
|
||||
|
||||
//コードを入れた後認証
|
||||
function code() {
|
||||
var code = $("#code").val();
|
||||
var url = localStorage.getItem("domain_" + acct_id);
|
||||
var start = "https://" + url + "/oauth/token";
|
||||
var id = localStorage.getItem("client_id");
|
||||
var secret = localStorage.getItem("client_secret");
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
grant_type: "authorization_code",
|
||||
redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
|
||||
client_id: id,
|
||||
client_secret: secret,
|
||||
code: code
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if (json["access_token"]) {
|
||||
localStorage.setItem(url + "_at", json["access_token"]);
|
||||
getdata();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//名前とか@とか取得
|
||||
function getdata() {
|
||||
var acct_id = 0;
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/verify_credentials";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
if (json.error) {
|
||||
console.error("Error:" + json.error);
|
||||
Materialize.toast("エラーが発生しました。しばらく待ってから再起動してください。Error:" + json.error,
|
||||
5000);
|
||||
return;
|
||||
}
|
||||
var obj = [{
|
||||
at: at,
|
||||
name: json["display_name"],
|
||||
domain: domain,
|
||||
user: json["acct"],
|
||||
prof: json["avatar"]
|
||||
}];
|
||||
var json = JSON.stringify(obj);
|
||||
console.log(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
localStorage.setItem("name_" + acct_id, json["display_name"]);
|
||||
localStorage.setItem("user_" + acct_id, json["acct"]);
|
||||
localStorage.setItem("user-id_" + acct_id, json["id"]);
|
||||
localStorage.setItem("prof_" + acct_id, json["avatar"]);
|
||||
$("#my-prof").attr("src", json["avatar"]);
|
||||
$("#auth").hide();
|
||||
$("#tl").show();
|
||||
parseColumn()
|
||||
ckdb();
|
||||
});
|
||||
}
|
||||
|
||||
//TheDesk独自のマストドンDBでMarkdownやBBCodeの対応、文字数制限をチェック
|
||||
function ckdb() {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var bbcode = domain + "_bbcode";
|
||||
var letters = domain + "_letters";
|
||||
var start = "https://desk.cutls.com/mastodon_data.json";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
console.log(json[letters]);
|
||||
if (json[bbcode]) {
|
||||
if (json[bbcode] == "enabled") {
|
||||
|
||||
} else {
|
||||
$("[data-activates='bbcode']").addClass("disabled");
|
||||
$("[data-activates='bbcode']").prop("disabled", true);
|
||||
}
|
||||
} else {
|
||||
$("[data-activates='bbcode']").addClass("disabled");
|
||||
$("[data-activates='bbcode']").addClass("disabled", true);
|
||||
}
|
||||
if (json[letters]) {
|
||||
$("#textarea").attr("data-length", json[letters]);
|
||||
} else {}
|
||||
if (json[domain + "_markdown"] == "enabled") {
|
||||
$(".markdown").show();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//サポートインスタンス取得
|
||||
function support() {
|
||||
var start = "https://desk.cutls.com/mastodon_data.json";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
//body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
Object.keys(json).forEach(function(key) {
|
||||
var instance = json[key];
|
||||
if (instance == "instance") {
|
||||
templete = '<button class="btn waves-effect" onclick="login(\'' + key +
|
||||
'\')">' + json[key + "_name"] + '(' + key + ')</button>';
|
||||
$("#support").append(templete);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//アカウントを選択…を実装
|
||||
function multi() {
|
||||
var multi = localStorage.getItem("multi");
|
||||
if (!multi) {
|
||||
var obj = [{
|
||||
at: localStorage.getItem(localStorage.getItem("domain_" + acct_id) + "_at"),
|
||||
name: localStorage.getItem("name_" + acct_id),
|
||||
domain: localStorage.getItem("domain_" + acct_id),
|
||||
user: localStorage.getItem("user_" + acct_id),
|
||||
prof: localStorage.getItem("prof_" + acct_id)
|
||||
}];
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
} else {
|
||||
var obj = JSON.parse(multi);
|
||||
}
|
||||
var templete;
|
||||
var last = localStorage.getItem("last-use");
|
||||
var sel;
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var acct = obj[key];
|
||||
var list = key * 1 + 1;
|
||||
if (key == last) {
|
||||
sel = "selected";
|
||||
} else {
|
||||
sel = "";
|
||||
}
|
||||
templete = '<option value="' + key + '" data-icon="' + acct.prof +
|
||||
'" class="left circle" ' + sel + '>' + acct.user + '@' + acct.domain +
|
||||
'</option>';
|
||||
$(".acct-sel").append(templete);
|
||||
$('select').material_select('update');
|
||||
});
|
||||
}
|
||||
//現在使用停止(Uzukiより前)
|
||||
function multiLogin(target) {
|
||||
var multi = localStorage.getItem("multi");
|
||||
var obj = JSON.parse(multi);
|
||||
var acct = obj[target];
|
||||
localStorage.setItem("domain_" + target, acct.domain);
|
||||
localStorage.setItem(domain + "_at", acct.at);
|
||||
localStorage.setItem("acct", target);
|
||||
location.href = "index.html";
|
||||
}
|
7
js/login/logout.js
Normal file
7
js/login/logout.js
Normal file
@@ -0,0 +1,7 @@
|
||||
//ログアウトします
|
||||
function logout(){
|
||||
localStorage.removeItem(localStorage.getItem("domain_"+acct_id)+"_at");
|
||||
localStorage.removeItem("domain_"+acct_id);
|
||||
location.href="index.html";
|
||||
todc();
|
||||
}
|
298
js/login/manager.js
Normal file
298
js/login/manager.js
Normal file
@@ -0,0 +1,298 @@
|
||||
//アカウントマネージャ
|
||||
//最初に読むやつ
|
||||
function load() {
|
||||
$("#acct-list").html("");
|
||||
var prof = localStorage.getItem("prof");
|
||||
$(".my-prof").attr("src", prof);
|
||||
var name = localStorage.getItem("name");
|
||||
$("#now-name").text(name);
|
||||
var user = localStorage.getItem("user");
|
||||
$("#now-user").text(user);
|
||||
var domain = localStorage.getItem("domain");
|
||||
$(".now-domain").text(domain);
|
||||
var multi = localStorage.getItem("multi");
|
||||
if (!multi) {
|
||||
var obj = [{
|
||||
at: localStorage.getItem(localStorage.getItem("domain_0") + "_at"),
|
||||
name: localStorage.getItem("name_0"),
|
||||
domain: localStorage.getItem("domain_0"),
|
||||
user: localStorage.getItem("user_0"),
|
||||
prof: localStorage.getItem("prof_0"),
|
||||
id: localStorage.getItem("user-id_0")
|
||||
}];
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
} else {
|
||||
var obj = JSON.parse(multi);
|
||||
}
|
||||
console.log(obj);
|
||||
var templete;
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var acct = obj[key];
|
||||
var list = key * 1 + 1;
|
||||
templete = '<div class="acct" id="acct_' + key + '">' + list +
|
||||
'.<img src="' + acct.prof + '" width="40" height="40"><div class="text">' +
|
||||
acct.name + ' <span class="gray">' + acct.user + '@' + acct.domain +
|
||||
'</span></div><button class="btn waves-effect disTar" onclick="data(\'' +
|
||||
acct.domain +
|
||||
'\')">インスタンスデータ表示</button><button class="btn waves-effect" onclick="refresh(' +
|
||||
key +
|
||||
')">情報更新</button><button class="btn waves-effect red disTar" onclick="multiDel(' +
|
||||
key + ')">削除</button><br></div>';
|
||||
$("#acct-list").append(templete);
|
||||
});
|
||||
var acctN = localStorage.getItem("acct");
|
||||
if (!acctN) {
|
||||
localStorage.setItem("acct", 0);
|
||||
var acctN = 0;
|
||||
}
|
||||
|
||||
}
|
||||
//最初に読む
|
||||
load();
|
||||
support();
|
||||
|
||||
//instances.social
|
||||
function data(domain) {
|
||||
$("#ins-upd").text("Loading...");
|
||||
$("#ins-add").text("Loading...");
|
||||
$("#ins-connect").text("Loading...");
|
||||
$("#ins-toot").text("Loading...");
|
||||
$("#ins-sys").text("Loading...");
|
||||
$("#ins-per").text("Loading...");
|
||||
$("#ins-user").text("Loading...");
|
||||
$("#ins-ver").text("Loading...");
|
||||
$("#ins-prof").attr('src', "./img/loading.svg");
|
||||
var start = "https://instances.social/api/1.0/instances/show?name=" + domain;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer tC8F6xWGWBUwGScyNevYlx62iO6fdQ4oIK0ad68Oo7ZKB8GQdGpjW9TKxBnIh8grAhvd5rw3iyP9JPamoDpeLQdz62EToPJUW99hDx8rfuJfGdjQuimZPTbIOx0woA5M'
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
if (!json.error) {
|
||||
$("#ins-upd").text(date(json.checked_at, 'full'));
|
||||
$("#ins-add").text(date(json.added_at, 'full'));
|
||||
$("#ins-connect").text(json.connections);
|
||||
$("#ins-toot").text(json.statuses);
|
||||
$("#ins-sys").text(date(json.updated_at, 'full'));
|
||||
$("#ins-per").text(json.uptime * 100);
|
||||
$("#ins-user").text(json.users);
|
||||
$("#ins-ver").text(json.version);
|
||||
$("#ins-prof").attr('src', json.thumbnail);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//アカウントデータ 消す
|
||||
function multiDel(target) {
|
||||
var multi = localStorage.getItem("multi");
|
||||
var obj = JSON.parse(multi);
|
||||
if (confirm(obj[target]["user"] + "@" + obj[target]["domain"] + "を削除します")) {
|
||||
obj.splice(target, 1);
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
load();
|
||||
}
|
||||
}
|
||||
|
||||
//サポートインスタンス
|
||||
function support() {
|
||||
var start = "https://desk.cutls.com/mastodon_data.json";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
Object.keys(json).forEach(function(key) {
|
||||
var instance = json[key];
|
||||
if (instance == "instance") {
|
||||
templete = '<button class="btn waves-effect" onclick="login(\'' + key +
|
||||
'\')">' + json[key + "_name"] + '(' + key + ')</button>';
|
||||
$("#support").append(templete);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//URL指定してポップアップ
|
||||
function login(url) {
|
||||
var multi = localStorage.getItem("multi");
|
||||
var obj = JSON.parse(multi);
|
||||
var ng;
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var acct = obj[key];
|
||||
if (acct.domain == url) {
|
||||
Materialize.toast(url + "は登録できません。同一インスタンスには一つのアカウントでしかログインできません。", 5000);
|
||||
ng = "true";
|
||||
return;
|
||||
}
|
||||
});
|
||||
if (ng) {
|
||||
return;
|
||||
}
|
||||
var start = "https://" + url + "/api/v1/apps";
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
scopes: 'read write follow',
|
||||
client_name: "TheDesk(PC)",
|
||||
redirect_uris: 'urn:ietf:wg:oauth:2.0:oob',
|
||||
website: "https://desk.cutls.com"
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var auth = "https://" + url + "/oauth/authorize?client_id=" + json[
|
||||
"client_id"] + "&client_secret=" + json["client_secret"] +
|
||||
"&response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=read+write+follow";
|
||||
localStorage.setItem("domain_tmp", url);
|
||||
localStorage.setItem("client_id", json["client_id"]);
|
||||
localStorage.setItem("client_secret", json["client_secret"]);
|
||||
$("#auth").show();
|
||||
$("#add").hide();
|
||||
window.open(auth);
|
||||
});
|
||||
}
|
||||
|
||||
//テキストボックスにURL入れた
|
||||
function instance() {
|
||||
var url = $("#url").val();
|
||||
login(url);
|
||||
}
|
||||
|
||||
//コード入れてAccessTokenゲット
|
||||
function code() {
|
||||
var code = $("#code").val();
|
||||
var url = localStorage.getItem("domain_tmp");
|
||||
localStorage.removeItem("domain_tmp");
|
||||
var start = "https://" + url + "/oauth/token";
|
||||
var id = localStorage.getItem("client_id");
|
||||
var secret = localStorage.getItem("client_secret");
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
grant_type: "authorization_code",
|
||||
redirect_uri: "urn:ietf:wg:oauth:2.0:oob",
|
||||
client_id: id,
|
||||
client_secret: secret,
|
||||
code: code
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if (json["access_token"]) {
|
||||
$("#auth").hide();
|
||||
$("#add").show();
|
||||
getdata(url, json["access_token"]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//ユーザーデータ取得
|
||||
function getdata(domain, at) {
|
||||
var start = "https://" + domain + "/api/v1/accounts/verify_credentials";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
if (json.error) {
|
||||
console.error("Error:" + json.error);
|
||||
Materialize.toast("エラーが発生しました。しばらく待ってから再起動してください。Error:" + json.error,
|
||||
5000);
|
||||
return;
|
||||
}
|
||||
var add = {
|
||||
at: at,
|
||||
name: json["display_name"],
|
||||
domain: domain,
|
||||
user: json["acct"],
|
||||
prof: json["avatar"],
|
||||
id: json["id"]
|
||||
};
|
||||
var multi = localStorage.getItem("multi");
|
||||
var obj = JSON.parse(multi);
|
||||
obj.push(add);
|
||||
console.log(obj);
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
load();
|
||||
});
|
||||
}
|
||||
|
||||
//ユーザーデータ更新
|
||||
function refresh(target) {
|
||||
var multi = localStorage.getItem("multi");
|
||||
var obj = JSON.parse(multi);
|
||||
var start = "https://" + obj[target].domain +
|
||||
"/api/v1/accounts/verify_credentials";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + obj[target].at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
if (json.error) {
|
||||
console.error("Error:" + json.error);
|
||||
Materialize.toast("エラーが発生しました。しばらく待ってから再起動してください。Error:" + json.error,
|
||||
5000);
|
||||
return;
|
||||
}
|
||||
var ref = {
|
||||
at: obj[target].at,
|
||||
name: json["display_name"],
|
||||
domain: obj[target].domain,
|
||||
user: json["acct"],
|
||||
prof: json["avatar"],
|
||||
id: json["id"]
|
||||
};
|
||||
obj[target] = ref;
|
||||
console.log(obj);
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
|
||||
load();
|
||||
});
|
||||
}
|
67
js/platform/end.js
Normal file
67
js/platform/end.js
Normal file
@@ -0,0 +1,67 @@
|
||||
//プラットフォーム別 最後に読むやつ
|
||||
//リンクを外部で開くか内部で出すか
|
||||
$(document).on('click', 'a', e => {
|
||||
var $a = $(e.target);
|
||||
var url = $a.attr('href');
|
||||
if (!url) {
|
||||
var url = $a.parent().attr('href');
|
||||
}
|
||||
var urls = url.match(/https?:\/\/([-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/);
|
||||
//hrefがhttp/httpsならブラウザで
|
||||
if (urls[0]) {
|
||||
const {
|
||||
shell
|
||||
} = require('electron');
|
||||
|
||||
shell.openExternal(url);
|
||||
} else {
|
||||
|
||||
location.href = url;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
//よく使うライブラリ
|
||||
/*マルチバイト用切り出し*/
|
||||
$.isSurrogatePear = function(upper, lower) {
|
||||
return 0xD800 <= upper && upper <= 0xDBFF && 0xDC00 <= lower && lower <=
|
||||
0xDFFF;
|
||||
};
|
||||
$.mb_strlen = function(str) {
|
||||
var ret = 0;
|
||||
for (var i = 0; i < str.length; i++, ret++) {
|
||||
var upper = str.charCodeAt(i);
|
||||
var lower = str.length > (i + 1) ? str.charCodeAt(i + 1) : 0;
|
||||
if ($.isSurrogatePear(upper, lower)) {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
$.mb_substr = function(str, begin, end) {
|
||||
var ret = '';
|
||||
for (var i = 0, len = 0; i < str.length; i++, len++) {
|
||||
var upper = str.charCodeAt(i);
|
||||
var lower = str.length > (i + 1) ? str.charCodeAt(i + 1) : 0;
|
||||
var s = '';
|
||||
if ($.isSurrogatePear(upper, lower)) {
|
||||
i++;
|
||||
s = String.fromCharCode(upper, lower);
|
||||
} else {
|
||||
s = String.fromCharCode(upper);
|
||||
}
|
||||
if (begin <= len && len < end) {
|
||||
ret += s;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
$.strip_tags = function(str, allowed) {
|
||||
allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || [])
|
||||
.join('');
|
||||
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
|
||||
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
|
||||
return str.replace(commentsAndPhpTags, '').replace(tags, function($0, $1) {
|
||||
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
|
||||
});
|
||||
};
|
3
js/platform/first.js
Normal file
3
js/platform/first.js
Normal file
@@ -0,0 +1,3 @@
|
||||
//jQuery読む
|
||||
window.jQuery = window.$ = require('./js/common/jquery.js');
|
||||
var Hammer = require('./js/common/hammer.min.js');
|
194
js/post/bb-md.js
Normal file
194
js/post/bb-md.js
Normal file
@@ -0,0 +1,194 @@
|
||||
//BBCodeとMarkdownの入力・パーサー
|
||||
//BOXのトグルボタン
|
||||
function mdToggle(){
|
||||
$(".markdown").toggleClass("hide");
|
||||
$(".anti-markdown").toggleClass("hide");
|
||||
if($(".markdown").hasClass("hide")){
|
||||
localStorage.setItem("md","hide");
|
||||
}else{
|
||||
localStorage.removeItem("md");
|
||||
}
|
||||
|
||||
}
|
||||
//最初に読み込みます(MD対応インスタンスかチェック)
|
||||
if(localStorage.getItem("md")=="hide"){
|
||||
$(".markdown").addClass("hide");
|
||||
$(".anti-markdown").removeClass("hide");
|
||||
}
|
||||
//タグを選んだ時に(BB版)
|
||||
function tagsel(tag){
|
||||
if(tag=="large" || tag=="size" || tag=="color" || tag=="colorhex"){
|
||||
var sub=$("#"+tag).val();
|
||||
var sub = sub.replace( /#/g , "" ) ;
|
||||
surroundHTML(tag+"="+sub,tag);
|
||||
}else if(tag=="flip=vertical" || tag=="flip=horizontal"){
|
||||
surroundHTML(tag,"flip");
|
||||
}else{
|
||||
surroundHTML(tag,tag);
|
||||
}
|
||||
$("#textarea").focus();
|
||||
}
|
||||
//HTMLをエスケープしてXSSを防ぐ
|
||||
function escape_html (string) {
|
||||
if(typeof string !== 'string') {
|
||||
return string;
|
||||
}
|
||||
return string.replace(/[&'`"<>]/g, function(match) {
|
||||
return {
|
||||
'&': '&',
|
||||
"'": ''',
|
||||
'`': '`',
|
||||
'"': '"',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
}[match]
|
||||
});
|
||||
}
|
||||
//PHPのnl2brと同様
|
||||
function nl2br(str) {
|
||||
str = str.replace(/\r\n/g, "<br />");
|
||||
str = str.replace(/(\n|\r)/g, "<br />");
|
||||
return str;
|
||||
}
|
||||
//テキストボックスで選択したやつをタグで囲む(BB版)
|
||||
function surroundHTML(tagS,tagE) {
|
||||
var target = document.getElementById("textarea");
|
||||
var pos = getAreaRange(target);
|
||||
|
||||
var val = target.value;
|
||||
var range = val.slice(pos.start, pos.end);
|
||||
var beforeNode = val.slice(0, pos.start);
|
||||
var afterNode = val.slice(pos.end);
|
||||
var insertNode;
|
||||
if (range || pos.start != pos.end) {
|
||||
insertNode = '[' + tagS + ']' + range + '[/' + tagE + ']';
|
||||
target.value = beforeNode + insertNode + afterNode;
|
||||
}
|
||||
|
||||
else if (pos.start == pos.end) {
|
||||
insertNode = '[' + tagS + ']' + '[/' + tagE + ']';
|
||||
target.value = beforeNode + insertNode + afterNode;
|
||||
}
|
||||
}
|
||||
function markdown(tag,ck,br){
|
||||
surroundMD(tag,tag,ck);
|
||||
$("#textarea").focus();
|
||||
}
|
||||
function surroundMD(tagS,tagE,ck,br) {
|
||||
var target = document.getElementById("textarea");
|
||||
var pos = getAreaRange(target);
|
||||
|
||||
var val = target.value;
|
||||
var range = val.slice(pos.start, pos.end);
|
||||
var beforeNode = val.slice(0, pos.start);
|
||||
var afterNode = val.slice(pos.end);
|
||||
var insertNode;
|
||||
if(br=="yes"){
|
||||
var br="\n";
|
||||
}else{
|
||||
var br="";
|
||||
}
|
||||
|
||||
if ((range || pos.start != pos.end )&& ck=="yes") {
|
||||
insertNode = tagS + range + tagE ;
|
||||
target.value = beforeNode + insertNode + br + afterNode;
|
||||
}
|
||||
|
||||
else if (pos.start == pos.end || ck=="no") {
|
||||
insertNode = tagS + range;
|
||||
target.value = beforeNode + insertNode + br + afterNode;
|
||||
}
|
||||
}
|
||||
|
||||
//テキストボックスの前後チェック
|
||||
function getAreaRange(obj) {
|
||||
var pos = new Object();
|
||||
if(window.getSelection()) {
|
||||
pos.start = obj.selectionStart;
|
||||
pos.end = obj.selectionEnd;
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
//Markdownのリンク挿入
|
||||
function markdownLink(){
|
||||
var linkIns="["+$("#linkt").val()+"]"+"("+$("#link2").val()+")";
|
||||
if(linkIns!="[]()"){
|
||||
$("#textarea").val($("#textarea").val()+linkIns);
|
||||
$("#linkt").val("");
|
||||
$("#link2").val("");
|
||||
$("#textarea").focus();
|
||||
}
|
||||
}
|
||||
//Markdownのimg挿入
|
||||
function markdownImage(){
|
||||
var imgIns="!["+$("#image").val()+"]"+"("+$("#image2").val()+")";
|
||||
if(imgIns!="![]()"){
|
||||
$("#textarea").val($("#textarea").val()+imgIns);
|
||||
$("#image").val("");
|
||||
$("#image2").val("");
|
||||
$("#textarea").focus();
|
||||
}
|
||||
}
|
||||
//文字数をチェック(hタグ用)
|
||||
function str_count(all, part) {
|
||||
return (all.match(new RegExp(part, "g")) || []).length;
|
||||
}
|
||||
|
||||
//プレビュー
|
||||
function preview(){
|
||||
$("#preview-field").show();
|
||||
$("#toot-field").hide();
|
||||
$("#preview-btn").hide();
|
||||
var bb=escape_html($("#textarea").val());
|
||||
//quote
|
||||
var bb=bb.replace(/>(.+)$/g,'<blockquote>$1<\/blockquote>');
|
||||
//spin
|
||||
var bb=bb.replace(/\[spin\](.+)\[\/spin\]/g,'<span class="fa fa-spin">$1<\/span>');
|
||||
//pulse
|
||||
var bb=bb.replace(/\[pulse\](.+)\[\/pulse\]/g,'<span class="bbcode-pulse-loading">$1<\/span>');
|
||||
//large
|
||||
var bb=bb.replace(/\[large=([0-9]{1,2})x\](.+)\[\/large\]/g,'<span class="fa fa-$1x">$2<\/span>');
|
||||
//vertical
|
||||
var bb=bb.replace(/\[flip=vertical\](.+)\[\/flip\]/g,'<span class="fa fa-flip-vertical">$1<\/span>');
|
||||
//horizontal
|
||||
var bb=bb.replace(/\[flip=horizontal\](.+)\[\/flip\]/g,'<span class="fa fa-flip-horizontal">$1<\/span>');
|
||||
//b
|
||||
var bb=bb.replace(/\[b\](.+)\[\/b\]/g,'<b>$1<\/b>');
|
||||
//i
|
||||
var bb=bb.replace(/\[i\](.+)\[\/i\]/g,'<i>$1<\/i>');
|
||||
//u
|
||||
var bb=bb.replace(/\[u\](.+)\[\/u\]/g,'<u>$1<\/u>');
|
||||
//s
|
||||
var bb=bb.replace(/\[s\](.+)\[\/s\]/g,'<s>$1<\/s>');
|
||||
//size
|
||||
var bb=bb.replace(/\[size=([0-9]{1,2})\](.+)\[\/size\]/g,'<span style="font-size:$1px">$2<\/span>');
|
||||
//colorhex
|
||||
var bb=bb.replace(/\[colorhex=([A-Fa-f0-9]+)\](.+)\[\/colorhex\]/g,'<span style="color:#$1">$2<\/span>');
|
||||
//code
|
||||
var bb=bb.replace(/`(.+)`/g,'<code>$1<\/code>');
|
||||
//index
|
||||
var m;
|
||||
m=bb.match(/^#{1,6}(.+)$/gm);
|
||||
if(m){
|
||||
for(let i = 0; i < m.length; i++) {
|
||||
var t=m[i].match(/^#{1,6}(.+)$/);
|
||||
var indexct='<h'+str_count(m[i],"#")+'>'+t[1]+'</h'+str_count(m[i],"#")+'>';
|
||||
var bb=bb.replace(new RegExp(m[i], ""),indexct);
|
||||
}
|
||||
}
|
||||
//img
|
||||
var bb=bb.replace(/!\[(.+)\]\((https:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\)/g,'<img src="$2" text="$1" style="width:100%">');
|
||||
//link
|
||||
var bb=bb.replace(/\[(.+)\]\((https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)\)/g,'<a href="$2" target="_blank">$1<\/a>');
|
||||
|
||||
$("#md-preview").html(nl2br(bb));
|
||||
}
|
||||
//Editで戻る
|
||||
function previewEdit(){
|
||||
$("#preview-field").hide();
|
||||
$("#toot-field").show();
|
||||
$("#preview-btn").show();
|
||||
$("#md-preview").html("");
|
||||
}
|
114
js/post/emoji.js
Normal file
114
js/post/emoji.js
Normal file
@@ -0,0 +1,114 @@
|
||||
//絵文字ピッカー
|
||||
//最初に読み込む
|
||||
$("#emoji-before").addClass("disabled");
|
||||
$("#emoji-next").addClass("disabled");
|
||||
|
||||
//絵文字ボタンのトグル
|
||||
function emoji() {
|
||||
var acct_id = $("#post-acct-sel").val();
|
||||
if ($("#emoji").hasClass("hide")) {
|
||||
$("#emoji").removeClass("hide")
|
||||
if (!localStorage.getItem("emoji_" + acct_id)) {
|
||||
var html =
|
||||
'<button class="btn waves-effect green" style="width:100%; padding:0; margin-top:0;" onclick="emojiGet(\'true\');">絵文字リスト取得</button>';
|
||||
$("#emoji-list").html(html);
|
||||
} else {
|
||||
emojiList('home');
|
||||
}
|
||||
} else {
|
||||
$("#emoji").addClass("hide")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//絵文字リスト挿入
|
||||
function emojiGet(parse) {
|
||||
$('#emoji-list').html('Loading...');
|
||||
var acct_id = $("#post-acct-sel").val();
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var start = "https://" + domain + "/api/v1/custom_emojis";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if (parse == "true") {
|
||||
$('#emoji-list').html('Parsing...');
|
||||
//絵文字をマストドン公式と同順にソート
|
||||
json.sort(function(a, b) {
|
||||
if (a.shortcode < b.shortcode) return -1;
|
||||
if (a.shortcode > b.shortcode) return 1;
|
||||
return 0;
|
||||
});
|
||||
localStorage.setItem("emoji_" + acct_id, JSON.stringify(json));
|
||||
} else {
|
||||
localStorage.setItem("emoji_" + acct_id, JSON.stringify(json));
|
||||
}
|
||||
localStorage.setItem("emojiseek", 0);
|
||||
emojiList('home')
|
||||
});
|
||||
}
|
||||
|
||||
//リストの描画
|
||||
function emojiList(target) {
|
||||
var acct_id = $("#post-acct-sel").val();
|
||||
var start = localStorage.getItem("emojiseek");
|
||||
if (target == "next") {
|
||||
var start = start * 1 + 127;
|
||||
localStorage.setItem("emojiseek", start);
|
||||
} else if (target == "before") {
|
||||
var start = start - 127;
|
||||
localStorage.setItem("emojiseek", start);
|
||||
} else {
|
||||
var start = 0;
|
||||
localStorage.getItem("emojiseek", 0)
|
||||
}
|
||||
var html = '';
|
||||
var obj = JSON.parse(localStorage.getItem("emoji_" + acct_id));
|
||||
var num = obj.length;
|
||||
if (num < start) {
|
||||
var start = 0;
|
||||
localStorage.setItem("emojiseek", start);
|
||||
}
|
||||
var page = Math.ceil(num / 126);
|
||||
$("#emoji-sum").text(page);
|
||||
var ct = Math.ceil(start / 126);
|
||||
if (ct == 0) {
|
||||
var ct = 1;
|
||||
$("#emoji-before").addClass("disabled");
|
||||
} else {
|
||||
$("#emoji-before").removeClass("disabled");
|
||||
}
|
||||
$("#emoji-next").removeClass("disabled");
|
||||
$("#emoji-count").text(ct);
|
||||
for (i = start; i < start + 126; i++) {
|
||||
var emoji = obj[i];
|
||||
if (emoji) {
|
||||
html = html + '<a onclick="emojiInsert(\':' + emoji.shortcode +
|
||||
':\')" class="pointer"><img src="' + emoji.url + '" width="20"></a>';
|
||||
}
|
||||
}
|
||||
$("#emoji-list").html(html);
|
||||
}
|
||||
|
||||
//絵文字など様々なものをテキストボックスに挿入
|
||||
function emojiInsert(code, del) {
|
||||
var now = $("#textarea").val();
|
||||
|
||||
if (!del) {
|
||||
$("#textarea").val(now + " " + code);
|
||||
emoji();
|
||||
} else {
|
||||
var regExp = new RegExp(del, "g");
|
||||
var now = now.replace(now, "");
|
||||
$("#textarea").val(now + " " + code);
|
||||
}
|
||||
$("#textarea").focus();
|
||||
}
|
132
js/post/img.js
Normal file
132
js/post/img.js
Normal file
@@ -0,0 +1,132 @@
|
||||
//ドラッグ・アンド・ドロップからアップロードまで。uiのimg.jsとは異なります。
|
||||
var obj = $("body");
|
||||
var system;
|
||||
//ドラッグスタート
|
||||
obj.on('dragstart', function(e) {
|
||||
system = "locked"
|
||||
});
|
||||
//何もなくファイルが通過
|
||||
obj.on('dragend', function(e) {
|
||||
system = "";
|
||||
});
|
||||
//ドラッグファイルが画面上に
|
||||
obj.on('dragenter', function(e) {
|
||||
if (system != "locked") {
|
||||
$("#drag").css('display', 'flex');
|
||||
more();
|
||||
}
|
||||
|
||||
});
|
||||
$("body").on('dragover', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
//ドロップした
|
||||
$("body").on('drop', function(e) {
|
||||
if (system != "locked") {
|
||||
$("#drag").css('display', 'none');
|
||||
e.preventDefault();
|
||||
var files = e.originalEvent.dataTransfer.files;
|
||||
pimg(files);
|
||||
}
|
||||
});
|
||||
//何もなくファイルが通過
|
||||
$("#drag").on('dragleave', function(e) {
|
||||
$("#drag").css('display', 'none');
|
||||
});
|
||||
|
||||
//複数アップ
|
||||
function pimg(files) {
|
||||
console.log(files);
|
||||
for (i = 0; i < files.length; i++) {
|
||||
handleFileUpload(files[i], obj);
|
||||
}
|
||||
}
|
||||
|
||||
//ドラッグ・アンド・ドロップを終了
|
||||
function closedrop() {
|
||||
$("#drag").css('display', 'none');
|
||||
}
|
||||
|
||||
//ファイルプレビュー
|
||||
function handleFileUpload(files, obj) {
|
||||
var fr = new FileReader();
|
||||
fr.onload = function(evt) {
|
||||
var b64 = evt.target.result;
|
||||
if (files["type"] == "image/png" || files["type"] == "image/jpeg" || files[
|
||||
"type"] == "image/gif") {
|
||||
var html = '<img src="' + b64 + '" style="width:50px; max-height:100px;">';
|
||||
$('#preview').append(html);
|
||||
} else {
|
||||
$('#preview').append(files["name"] + "はプレビューできません");
|
||||
}
|
||||
$('#b64-box').val(b64);
|
||||
var ret = media(b64, files["type"])
|
||||
}
|
||||
fr.readAsDataURL(files);
|
||||
$("#mec").append(files["name"] + "/");
|
||||
}
|
||||
|
||||
//ファイルアップロード
|
||||
function media(b64, type) {
|
||||
$("#toot-post-btn").prop("disabled", true);
|
||||
todo("Image Upload...");
|
||||
var media = toBlob(b64, type);
|
||||
console.log(media);
|
||||
var fd = new FormData();
|
||||
fd.append('file', media);
|
||||
var acct_id = $("#post-acct-sel").val();
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/media";
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: fd
|
||||
}).then(function(response) {
|
||||
console.log(response)
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
var img = localStorage.getItem("img");
|
||||
if (!img) {
|
||||
var img = "no-act";
|
||||
}
|
||||
if (img != "inline") {
|
||||
if ($("#media").val()) {
|
||||
$("#media").val($("#media").val() + ',' + json["id"]);
|
||||
} else {
|
||||
$("#media").val(json["id"]);
|
||||
}
|
||||
}
|
||||
if (img == "url") {
|
||||
$("#textarea").val($("#textarea").val() + " " + json["text_url"])
|
||||
}
|
||||
todc();
|
||||
$("#toot-post-btn").prop("disabled", false);
|
||||
});
|
||||
}
|
||||
|
||||
//Base64からBlobへ
|
||||
function toBlob(base64, type) {
|
||||
var bin = atob(base64.replace(/^.*,/, ''));
|
||||
var buffer = new Uint8Array(bin.length);
|
||||
for (var i = 0; i < bin.length; i++) {
|
||||
buffer[i] = bin.charCodeAt(i);
|
||||
}
|
||||
// Blobを作成
|
||||
try {
|
||||
var blob = new Blob([new Uint8Array(buffer)], {
|
||||
type: type
|
||||
});
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
97
js/post/post.js
Normal file
97
js/post/post.js
Normal file
@@ -0,0 +1,97 @@
|
||||
/*投稿系*/
|
||||
//投稿
|
||||
function post() {
|
||||
var str = $("#textarea").val();
|
||||
var acct_id = $("#post-acct-sel").val();
|
||||
localStorage.setItem("last-use", acct_id);
|
||||
todo("Posting");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses";
|
||||
var reply = $("#reply").val();
|
||||
var media = $("#media").val();
|
||||
if ($("#nsfw").hasClass("nsfw-avail")) {
|
||||
var nsfw = "true";
|
||||
} else {
|
||||
var nsfw = "false";
|
||||
}
|
||||
var vis = $("#vis").text();
|
||||
if ($("#cw").hasClass("cw-avail")) {
|
||||
var spo = $("#cw-text").val();
|
||||
} else {
|
||||
var spo = "";
|
||||
}
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({
|
||||
status: str,
|
||||
in_reply_to_id: reply,
|
||||
media_ids: media.split(","),
|
||||
sensitive: nsfw,
|
||||
spoiler_text: spo,
|
||||
visibility: vis
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
var box = localStorage.getItem("box");
|
||||
if (box == "yes") {
|
||||
hide();
|
||||
}
|
||||
todc();
|
||||
clear();
|
||||
});
|
||||
}
|
||||
|
||||
//クリア(Shift+C)
|
||||
function clear() {
|
||||
$("#textarea").val("");
|
||||
$("#textarea").attr("placeholder", "象");
|
||||
$("#reply").val("");
|
||||
$("#media").val("");
|
||||
var cwt = localStorage.getItem("cw-text");
|
||||
if (cwt) {
|
||||
$("#cw-text").val(cwt);
|
||||
} else {
|
||||
$("#cw-text").val("");
|
||||
}
|
||||
$("#cw").addClass("blue");
|
||||
$("#cw").removeClass("yellow");
|
||||
$("#cw").removeClass("cw-avail");
|
||||
$("#rec").text("いいえ");
|
||||
$("#mec").text("なし");
|
||||
var vis = localStorage.getItem("vis");
|
||||
if (!vis) {
|
||||
$("#vis").text("public");
|
||||
} else {
|
||||
if (vis == "memory") {
|
||||
localStorage.setItem("vis-memory", $("#vis").text());
|
||||
} else {
|
||||
$("#vis").text(vis);
|
||||
}
|
||||
}
|
||||
$("#nsfw").addClass("blue");
|
||||
$("#nsfw").removeClass("yellow");
|
||||
$("#nsi").html("lock_open");
|
||||
$("#nsfw").removeClass("nsfw-avail");
|
||||
$("#nsc").text("なし");
|
||||
$("#drag").css("background-color", "#e0e0e0");
|
||||
$("#preview").html("");
|
||||
if ($("#post-box").hasClass("post-more")) {
|
||||
$("#file-wrap").html(
|
||||
'<input class="more-show" style="display:inline-block;" type="file" name="pic" id="upfile" onchange="pimg(document.getElementById(\'upfile\').files);" multiple>'
|
||||
);
|
||||
} else {
|
||||
$("#file-wrap").html(
|
||||
'<input class="more-show" type="file" name="pic" id="upfile" onchange="pimg(document.getElementById(\'upfile\').files);" multiple>'
|
||||
);
|
||||
}
|
||||
}
|
9
js/post/reply.js
Normal file
9
js/post/reply.js
Normal file
@@ -0,0 +1,9 @@
|
||||
/*リプライ*/
|
||||
function re(id,at){
|
||||
show();
|
||||
$("#reply").val(id);
|
||||
var te=$("#textarea").val();
|
||||
$("#textarea").val("@"+at+" "+te);
|
||||
$("#rec").text("はい");
|
||||
$("#textarea").attr("placeholder","返信モードです。クリアするときはShift+Cを押してください。");
|
||||
}
|
50
js/post/secure.js
Normal file
50
js/post/secure.js
Normal file
@@ -0,0 +1,50 @@
|
||||
/*保護系*/
|
||||
//画像保護
|
||||
function nsfw(){
|
||||
if($("#nsfw").hasClass("nsfw-avail")){
|
||||
$("#nsfw").addClass("blue");
|
||||
$("#nsfw").removeClass("yellow");
|
||||
$("#nsi").html("lock_open");
|
||||
$("#nsfw").removeClass("nsfw-avail");
|
||||
$("#nsc").text("なし");
|
||||
}else{
|
||||
$("#nsfw").removeClass("blue");
|
||||
$("#nsfw").addClass("yellow");
|
||||
$("#nsi").html("lock_outline");
|
||||
$("#nsfw").addClass("nsfw-avail");
|
||||
$("#nsc").text("あり");
|
||||
}
|
||||
}
|
||||
|
||||
//投稿公開範囲
|
||||
function vis(set){
|
||||
$("#vis").text(set);
|
||||
var vis=localStorage.getItem("vis");
|
||||
if(vis=="memory"){
|
||||
localStorage.setItem("vis-memory",set);
|
||||
}
|
||||
}
|
||||
|
||||
//コンテンツワーニング
|
||||
function cw(){
|
||||
if($("#cw").hasClass("cw-avail")){
|
||||
$("#cw-text").val();
|
||||
$("#cw-text").hide();
|
||||
$("#cw").addClass("blue");
|
||||
$("#cw").removeClass("yellow");
|
||||
$("#cw").removeClass("cw-avail");
|
||||
}else{
|
||||
$("#cw-text").show();
|
||||
$("#cw").removeClass("blue");
|
||||
$("#cw").addClass("yellow");
|
||||
$("#cw").addClass("cw-avail");
|
||||
var cwt=localStorage.getItem("cw-text");
|
||||
if(cwt){
|
||||
$("#cw-text").val(cwt);
|
||||
}
|
||||
}
|
||||
}
|
||||
//TLでコンテンツワーニングを表示トグル
|
||||
function cw_show(id){
|
||||
$(".cw_hide_"+id).toggleClass("cw");
|
||||
}
|
268
js/post/status.js
Normal file
268
js/post/status.js
Normal file
@@ -0,0 +1,268 @@
|
||||
//お気に入り登録やブースト等、フォローやブロック等
|
||||
//お気に入り登録
|
||||
function fav(id, acct_id) {
|
||||
if ($("#pub_" + id).hasClass("faved")) {
|
||||
var flag = "unfavourite";
|
||||
} else {
|
||||
var flag = "favourite";
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id + "/" + flag;
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
$("#pub_" + id + " .fav_ct").text(json.favourites_count);
|
||||
if (!json.reblog) {
|
||||
$("#pub_" + id + " .rt_ct").text(json.reblogs_count - 1);
|
||||
} else {
|
||||
$("#pub_" + id + " .rt_ct").text(json.reblog.reblogs_count);
|
||||
}
|
||||
if ($("#pub_" + id).hasClass("faved")) {
|
||||
$("#pub_" + id).removeClass("faved");
|
||||
$("#fav_" + id).removeClass("yellow-text");
|
||||
} else {
|
||||
$("#pub_" + id).addClass("faved");
|
||||
$("#fav_" + id).addClass("yellow-text");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//ブースト
|
||||
function rt(id, acct_id) {
|
||||
if ($("#pub_" + id).hasClass("rted")) {
|
||||
var flag = "unreblog";
|
||||
} else {
|
||||
var flag = "reblog";
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id + "/" + flag;
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
$("#pub_" + id + " .fav_ct").text(json.favourites_count);
|
||||
if (!json.reblog) {
|
||||
$("#pub_" + id + " .rt_ct").text(json.reblogs_count - 1);
|
||||
} else {
|
||||
$("#pub_" + id + " .rt_ct").text(json.reblog.reblogs_count);
|
||||
}
|
||||
|
||||
if ($("#pub_" + id).hasClass("rted")) {
|
||||
$("#pub_" + id).removeClass("rted");
|
||||
$("#rt_" + id).removeClass("teal-text");
|
||||
} else {
|
||||
$("#pub_" + id).addClass("rted");
|
||||
$("#rt_" + id).addClass("teal-text");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//フォロー
|
||||
function follow(acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var id = $("#his-data").attr("user-id");
|
||||
if ($("#his-data").hasClass("following")) {
|
||||
var flag = "unfollow";
|
||||
} else {
|
||||
var flag = "follow";
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + id + "/" + flag;
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if ($("#his-data").hasClass("following")) {
|
||||
$("#his-data").removeClass("following");
|
||||
$("#his-follow-btn").text("フォロー");
|
||||
} else {
|
||||
$("#his-data").addClass("following");
|
||||
$("#his-follow-btn").text("フォロー解除");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//ブロック
|
||||
function block(acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var id = $("#his-data").attr("user-id");
|
||||
if ($("#his-data").hasClass("blocking")) {
|
||||
var flag = "unblock";
|
||||
} else {
|
||||
var flag = "block";
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + id + "/" + flag;
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if ($("#his-data").hasClass("blocking")) {
|
||||
$("#his-data").removeClass("blocking");
|
||||
$("#his-block-btn").text("ブロック");
|
||||
} else {
|
||||
$("#his-data").addClass("blocking");
|
||||
$("#his-block-btn").text("ブロック解除");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//ミュート
|
||||
function mute(acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var id = $("#his-data").attr("user-id");
|
||||
if ($("#his-data").hasClass("muting")) {
|
||||
var flag = "unmute";
|
||||
} else {
|
||||
var flag = "mute";
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + id + "/" + flag;
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if ($("#his-data").hasClass("muting")) {
|
||||
$("#his-data").removeClass("muting");
|
||||
$("#his-mute-btn").text("ミュート");
|
||||
} else {
|
||||
$("#his-data").addClass("muting");
|
||||
$("#his-mute-btn").text("ミュート解除");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//投稿削除
|
||||
function del(id, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id;
|
||||
fetch(start, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
//ここで消さなくてもStreamingが消す
|
||||
//$("#pub_"+id).hide();
|
||||
});
|
||||
}
|
||||
|
||||
//フォロリク
|
||||
function request(id, flag, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/follow_requests/" + id + "/" + flag;
|
||||
fetch(start, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
showReq();
|
||||
});
|
||||
}
|
||||
|
||||
//ドメインブロック(未実装)
|
||||
function domainblock(add, flag, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/domain_blocks"
|
||||
fetch(start, {
|
||||
method: flag,
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({
|
||||
domain: add
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
showDom();
|
||||
});
|
||||
}
|
||||
|
||||
function addDomainblock() {
|
||||
var domain = $("#domainblock").val();
|
||||
domainblock(domain, 'POST');
|
||||
}
|
70
js/post/suggest.js
Normal file
70
js/post/suggest.js
Normal file
@@ -0,0 +1,70 @@
|
||||
//入力時にハッシュタグと@をサジェスト
|
||||
var timer = null;
|
||||
|
||||
var input = document.getElementById("textarea");
|
||||
|
||||
var prev_val = input.value;
|
||||
var oldSuggest;
|
||||
var suggest;
|
||||
input.addEventListener("focus", function() {
|
||||
$("#suggest").html("");
|
||||
window.clearInterval(timer);
|
||||
timer = window.setInterval(function() {
|
||||
var new_val = input.value;
|
||||
if (prev_val != new_val) {
|
||||
var tag = new_val.match(/#(\S{3,})/);
|
||||
var acct = new_val.match(/@(\S{3,})/);
|
||||
if (tag && tag[1]) {
|
||||
var q = tag[1];
|
||||
} else if (acct[1]) {
|
||||
var q = acct[1];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
suggest = "https://" + domain + "/api/v1/search?q=" + q
|
||||
if (suggest != oldSuggest) {
|
||||
console.log(suggest)
|
||||
fetch(suggest, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
if (json.hashtags[0] && tag[1]) {
|
||||
var tags = "";
|
||||
Object.keys(json.hashtags).forEach(function(key4) {
|
||||
var tag = json.hashtags[key4];
|
||||
tags = tags + '<a onclick="emojiInsert(\'#' + tag + '\',\'#' + q +
|
||||
'\')" class="pointer">#' + tag + '</a> ';
|
||||
});
|
||||
$("#suggest").html("Tags:" + tags);
|
||||
} else if (json.accounts[0] && acct[1]) {
|
||||
var accts = "";
|
||||
Object.keys(json.accounts).forEach(function(key3) {
|
||||
var acct = json.accounts[key3];
|
||||
accts = accts + '<a onclick="emojiInsert(\'@' + acct.acct +
|
||||
'\',\'@' + q + '\')" class="pointer">@' + acct.acct + '</a> ';
|
||||
});
|
||||
$("#suggest").html("@:" + accts);
|
||||
} else {
|
||||
$("#suggest").html("Not Found");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
oldSuggest = suggest;
|
||||
prev_value = new_val;
|
||||
}, 1000);
|
||||
}, false);
|
||||
|
||||
input.addEventListener("blur", function() {
|
||||
window.clearInterval(timer);
|
||||
}, false);
|
72
js/tl/card.js
Normal file
72
js/tl/card.js
Normal file
@@ -0,0 +1,72 @@
|
||||
//カード処理やメンション、ハッシュタグの別途表示
|
||||
//全てのTL処理で呼び出し
|
||||
function additional(acct_id, tlid) {
|
||||
//メンション系
|
||||
$(".mention").attr("href", "#");
|
||||
//トゥートサムネ
|
||||
$("#timeline_" + tlid + " .toot a:not(.parsed)").each(function(i, elem) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var card = localStorage.getItem("card_" + tlid);
|
||||
var text = $(this).attr('href');
|
||||
var urls = text.match(
|
||||
/https?:\/\/([-a-zA-Z0-9@.]+)\/media\/([-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)/
|
||||
);
|
||||
if (urls) {
|
||||
$(this).remove();
|
||||
} else if (!card) {
|
||||
|
||||
var id = $(this).parents('.cvo').attr("toot-id");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id + "/card";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
//body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
if (json.title) {
|
||||
$("[toot-id=" + id + "] .additional").html(
|
||||
"<span class=\"gray\">URLチェック:<br>Title:" + json.title + "<br>" +
|
||||
json.description + "</span>");
|
||||
}
|
||||
if (json.html) {
|
||||
$("[toot-id=" + id + "] .additional").html(json.html);
|
||||
|
||||
}
|
||||
if (json.title) {
|
||||
$("[toot-id=" + id + "] a:not(.parsed)").addClass("parsed");
|
||||
$("[toot-id=" + id + "]").addClass("parsed");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//各TL上方のLink[On/Off]
|
||||
function cardToggle(tlid) {
|
||||
var card = localStorage.getItem("card_" + tlid);
|
||||
if (!card) {
|
||||
localStorage.setItem("card_" + tlid, "true");
|
||||
$("#sta-card-" + tlid).text("Off");
|
||||
} else {
|
||||
localStorage.removeItem("card_" + tlid);
|
||||
$("#sta-card-" + tlid).text("On");
|
||||
}
|
||||
}
|
||||
//各TL上方のLink[On/Off]をチェック
|
||||
function cardCheck(tlid) {
|
||||
var card = localStorage.getItem("card_" + tlid);
|
||||
if (!card) {
|
||||
$("#sta-card-" + tlid).text("On");
|
||||
} else {
|
||||
$("#sta-card-" + tlid).text("Off");
|
||||
}
|
||||
}
|
149
js/tl/datails.js
Normal file
149
js/tl/datails.js
Normal file
@@ -0,0 +1,149 @@
|
||||
//トゥートの詳細
|
||||
function details(id, acct_id) {
|
||||
$(".toot-reset").html("トゥートはありません");
|
||||
var html = $("#pub_" + id).html();
|
||||
$("#toot-this").html(html);
|
||||
$('#tootmodal').modal('open');
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
$("#toot-this .fav_ct").text(json.favourites_count);
|
||||
$("#toot-this .rt_ct").text(json.reblogs_count);
|
||||
if (json.in_reply_to_id) {
|
||||
replyTL(json.in_reply_to_id, acct_id);
|
||||
}
|
||||
context(id, acct_id);
|
||||
faved(id, acct_id);
|
||||
rted(id, acct_id);
|
||||
});
|
||||
}
|
||||
|
||||
//返信タイムライン
|
||||
function replyTL(id, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse([json]);
|
||||
$("#toot-reply").prepend(templete);
|
||||
jQuery("time.timeago").timeago();
|
||||
if (json.in_reply_to_id) {
|
||||
replyTL(json.in_reply_to_id, acct_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//コンテクストってなんですか
|
||||
function context(id, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id + "/context";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json.descendants);
|
||||
$("#toot-after").html(templete);
|
||||
beforeToot(id, acct_id);
|
||||
jQuery("time.timeago").timeago();
|
||||
});
|
||||
}
|
||||
|
||||
//前のトゥート(Back TL)
|
||||
function beforeToot(id, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain +
|
||||
"/api/v1/timelines/public?local=true&max_id=" + id;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json);
|
||||
$("#toot-before").html(templete);
|
||||
jQuery("time.timeago").timeago();
|
||||
});
|
||||
}
|
||||
|
||||
//ふぁぼ一覧
|
||||
function faved(id, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id + "/favourited_by";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json);
|
||||
$("#toot-fav").html(templete);
|
||||
});
|
||||
}
|
||||
|
||||
//ブースト一覧
|
||||
function rted(id, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/statuses/" + id + "/reblogged_by";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json);
|
||||
$("#toot-rt").html(templete);
|
||||
});
|
||||
}
|
69
js/tl/date.js
Normal file
69
js/tl/date.js
Normal file
@@ -0,0 +1,69 @@
|
||||
//日付パーサー
|
||||
function date(str, datetype) {
|
||||
if (datetype == "relative") {
|
||||
return '<time class="timeago" datetime="' + str + '"></time>';
|
||||
} else {
|
||||
var date = new Date(str);
|
||||
if (datetype == "unix") {
|
||||
var unixm = date.getTime();
|
||||
return Math.floor(unixm / 1000);
|
||||
}
|
||||
var now = new Date();
|
||||
var month = date.getMonth() + 1;
|
||||
if (date.getMinutes() < 10) {
|
||||
var min = "0" + date.getMinutes();
|
||||
} else {
|
||||
var min = date.getMinutes();
|
||||
}
|
||||
if (date.getSeconds() < 10) {
|
||||
var sec = "0" + date.getSeconds();
|
||||
} else {
|
||||
var sec = date.getSeconds();
|
||||
}
|
||||
if (datetype == "full") {
|
||||
var ret = date.getFullYear() + "年" + month + "月" + date.getDate() + "日 " +
|
||||
date.getHours() + ":" + min + ":" + sec;
|
||||
}
|
||||
if (date.getFullYear() == now.getFullYear()) {
|
||||
if (date.getMonth() == now.getMonth()) {
|
||||
if (date.getDate() == now.getDate()) {
|
||||
if (datetype == "medium") {
|
||||
var ret = '<time class="timeago" datetime="' + str + '"></time>';
|
||||
} else {
|
||||
var ret = date.getHours() + ":" + min + ":" + sec;
|
||||
}
|
||||
|
||||
} else {
|
||||
var ret = month + "月" + date.getDate() + "日 " + date.getHours() + ":" +
|
||||
min + ":" + sec;
|
||||
}
|
||||
} else {
|
||||
var ret = month + "月" + date.getDate() + "日 " + date.getHours() + ":" + min +
|
||||
":" + sec;
|
||||
}
|
||||
} else {
|
||||
var ret = date.getFullYear() + "年" + month + "月" + date.getDate() + "日 " +
|
||||
date.getHours() + ":" + min + ":" + sec;
|
||||
}
|
||||
if (datetype == "double") {
|
||||
return '<time class="timeago" datetime="' + str + '"></time>/' + ret;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//特殊フォーマット(インスタンス情報で利用)
|
||||
function crat(str) {
|
||||
var date = new Date(str);
|
||||
|
||||
format_str = 'YYYY-MM-DD hh:mm:ss';
|
||||
format_str = format_str.replace(/YYYY/g, date.getFullYear());
|
||||
format_str = format_str.replace(/MM/g, date.getMonth());
|
||||
format_str = format_str.replace(/DD/g, date.getDate());
|
||||
format_str = format_str.replace(/hh/g, date.getHours());
|
||||
format_str = format_str.replace(/mm/g, date.getMinutes());
|
||||
format_str = format_str.replace(/ss/g, date.getSeconds());
|
||||
|
||||
return format_str;
|
||||
}
|
231
js/tl/mix.js
Normal file
231
js/tl/mix.js
Normal file
@@ -0,0 +1,231 @@
|
||||
//Integrated TL
|
||||
function mixtl(acct_id, tlid) {
|
||||
var type = "mix";
|
||||
localStorage.removeItem("morelock")
|
||||
$("#notice_" + tlid).text("Integrated TL");
|
||||
localStorage.setItem("now", type);
|
||||
todo("Integrated TL Loading...(Local)");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
//まずLocal
|
||||
var start = "https://" + domain + "/api/v1/timelines/public?local=true";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
//パースして描画
|
||||
var templete = parse(json, 'mix', acct_id);
|
||||
$("#timeline_" + tlid).html(templete[0]);
|
||||
|
||||
jQuery("time.timeago").timeago();
|
||||
$(window).scrollTop(0);
|
||||
var locals = templete[1];
|
||||
todo("Integrated TL Loading...(Home)");
|
||||
//Home
|
||||
var start = "https://" + domain + "/api/v1/timelines/home";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(obj) {
|
||||
//ホームのオブジェクトをUnix時間で走査
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var skey = obj.length - key - 1;
|
||||
var toot = obj[skey];
|
||||
var id = toot.id;
|
||||
var tarunix = date(toot.created_at, 'unix');
|
||||
var beforekey2;
|
||||
var key2;
|
||||
//ホームのオブジェクトに対してLocalのオブジェクトを時間走査
|
||||
Object.keys(locals).forEach(function(key2) {
|
||||
if (!$("#timeline_" + tlid + " [toot-id=" + obj[0].id + "]").length &&
|
||||
key2 < date(obj[0].created_at, 'unix')) {
|
||||
$("#timeline_" + tlid + " .cvo").first().prepend(parse([obj[0]],
|
||||
'home', acct_id));
|
||||
}
|
||||
if (!$("#timeline_" + tlid + " [toot-id=" + toot.id + "]").length) {
|
||||
if (key2 > tarunix) {
|
||||
var local = locals[key2];
|
||||
$("#timeline_" + tlid + " [toot-id=" + local + "]").append(parse(
|
||||
[toot], 'home', acct_id));
|
||||
tarunix = 0;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
todc();
|
||||
mixre(acct_id, tlid);
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//Streamingに接続
|
||||
function mixre(acct_id, tlid) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var type = "mix";
|
||||
localStorage.setItem("now", type);
|
||||
var startHome = "wss://" + domain +
|
||||
"/api/v1/streaming/?stream=user&access_token=" + at;
|
||||
|
||||
var startLocal = "wss://" + domain +
|
||||
"/api/v1/streaming/?stream=public:local&access_token=" + at;
|
||||
var wshid = websocketHome.length;
|
||||
var wslid = websocketLocal.length;
|
||||
websocketHome[wshid] = new WebSocket(startHome);
|
||||
websocketLocal[wslid] = new WebSocket(startLocal);
|
||||
websocketHome[wshid].onopen = function(mess) {
|
||||
console.log("Connect Streaming API(Home)");
|
||||
}
|
||||
websocketLocal[wslid].onopen = function(mess) {
|
||||
console.log("Connect Streaming API(Local)");
|
||||
}
|
||||
websocketLocal[wslid].onmessage = function(mess) {
|
||||
console.log("Receive Streaming API:");
|
||||
|
||||
var obj = JSON.parse(JSON.parse(mess.data).payload);
|
||||
console.log(obj);
|
||||
var type = JSON.parse(mess.data).event;
|
||||
if (type == "delete") {
|
||||
$("[toot-id=" + obj + "]").hide();
|
||||
} else if (type == "update") {
|
||||
var templete = parse([obj], '', acct_id);
|
||||
if (!$("#timeline_" + tlid + " [toot-id=" + obj.id + "]").length) {
|
||||
var pool = localStorage.getItem("pool_" + tlid);
|
||||
if (pool) {
|
||||
pool = templete + pool;
|
||||
} else {
|
||||
pool = templete
|
||||
}
|
||||
localStorage.setItem("pool_" + tlid, pool);
|
||||
scrollck();
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
todc();
|
||||
}
|
||||
}
|
||||
}
|
||||
websocketHome[wshid].onmessage = function(mess) {
|
||||
console.log("Receive Streaming API:(Home)");
|
||||
|
||||
var obj = JSON.parse(JSON.parse(mess.data).payload);
|
||||
console.log(obj);
|
||||
var type = JSON.parse(mess.data).event;
|
||||
if (type == "delete") {
|
||||
$("[toot-id=" + obj + "]").hide();
|
||||
} else if (type == "update") {
|
||||
var templete = parse([obj], '', acct_id);
|
||||
if (!$("#timeline_" + tlid + " [toot-id=" + obj.id + "]").length) {
|
||||
if ($(window).scrollTop() > 0) {
|
||||
var pool = localStorage.getItem("pool");
|
||||
if (pool) {
|
||||
pool = templete + pool;
|
||||
} else {
|
||||
pool = templete
|
||||
}
|
||||
localStorage.setItem("pool", pool);
|
||||
} else {
|
||||
$("#timeline_" + tlid).prepend(templete);
|
||||
}
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
}
|
||||
}
|
||||
}
|
||||
websocketLocal[wslid].onerror = function(error) {
|
||||
console.error('WebSocket Error ' + error);
|
||||
};
|
||||
websocketHome[wshid].onerror = function(error) {
|
||||
console.error('WebSocket Error ' + error);
|
||||
};
|
||||
}
|
||||
|
||||
//ある程度のスクロールで発火
|
||||
function mixmore(tlid) {
|
||||
var multi = localStorage.getItem("column");
|
||||
var obj = JSON.parse(multi);
|
||||
var acct_id = obj[tlid].domain;
|
||||
todo("Integrated TL MoreLoading...(Local)");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var sid = $("#timeline_" + tlid + " .cvo").last().attr("toot-id");
|
||||
var start = "https://" + domain +
|
||||
"/api/v1/timelines/public?local=true&max_id=" + sid;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json, 'mix', acct_id);
|
||||
$("#timeline_" + tlid).append(templete[0]);
|
||||
var locals = templete[1];
|
||||
todo("Integrated TL MoreLoading...(Home)");
|
||||
console.log(sid);
|
||||
var start = "https://" + domain + "/api/v1/timelines/home?max_id=" + sid;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(obj) {
|
||||
if (!$("[toot-id=" + obj[0].id + "]").length) {
|
||||
$("#timeline_" + tlid + " .cvo").first().prepend(parse([obj[0]], 'home',
|
||||
acct_id));
|
||||
}
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var skey = obj.length - key - 1;
|
||||
var toot = obj[skey];
|
||||
var id = toot.id;
|
||||
var tarunix = date(toot.created_at, 'unix');
|
||||
var beforekey2;
|
||||
var key2;
|
||||
Object.keys(locals).forEach(function(key2) {
|
||||
if (!$("[toot-id=" + toot.id + "]").length) {
|
||||
if (key2 > tarunix) {
|
||||
var local = locals[key2];
|
||||
$("[toot-id=" + local + "]").append(parse([toot], 'home',
|
||||
acct_id));
|
||||
tarunix = 0;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
todc();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
293
js/tl/notification.js
Normal file
293
js/tl/notification.js
Normal file
@@ -0,0 +1,293 @@
|
||||
//通知
|
||||
//取得+Streaming接続
|
||||
function notf(acct_id, tlid, sys) {
|
||||
todo("Notifications Loading...");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/notifications";
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
//body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parseNotf(json, -1, tlid, acct_id);
|
||||
if (sys == "direct") {
|
||||
$("#timeline_" + tlid).html(templete[0]);
|
||||
} else {
|
||||
$("#notifications_" + tlid).html(templete[0]);
|
||||
}
|
||||
|
||||
jQuery("time.timeago").timeago();
|
||||
$("#notf-box").addClass("fetched");
|
||||
todc();
|
||||
});
|
||||
var start = "wss://" + domain + "/api/v1/streaming/?stream=user&access_token=" +
|
||||
at;
|
||||
|
||||
console.log(start);
|
||||
var websocket = new WebSocket(start);
|
||||
console.log(websocket);
|
||||
websocket.onopen = function(mess) {
|
||||
console.log("Connect Streaming API:");
|
||||
console.log(mess);
|
||||
}
|
||||
websocket.onmessage = function(mess) {
|
||||
console.log("Receive Streaming API:");
|
||||
|
||||
var obj = JSON.parse(JSON.parse(mess.data).payload);
|
||||
console.log(obj);
|
||||
var type = JSON.parse(mess.data).event;
|
||||
if (type == "notification") {
|
||||
var popup = localStorage.getItem("popup");
|
||||
if (!popup) {
|
||||
popup = 0;
|
||||
}
|
||||
var templete = parseNotf([obj], popup, tlid, acct_id);
|
||||
var notices = templete[1];
|
||||
console.log(templete);
|
||||
if (sys == "direct") {
|
||||
$("#timeline_" + tlid).prepend(templete[0]);
|
||||
} else {
|
||||
$("#notifications_" + tlid).prepend(templete[0]);
|
||||
}
|
||||
jQuery("time.timeago").timeago();
|
||||
}
|
||||
|
||||
}
|
||||
websocket.onerror = function(error) {
|
||||
console.error('WebSocket Error ' + error);
|
||||
};
|
||||
}
|
||||
|
||||
//通知トグルボタン
|
||||
function notfToggle(acct, tlid) {
|
||||
$("#notf-box_" + tlid).toggleClass("hide");
|
||||
if (!$("#notf-box_" + tlid).hasClass("fetched")) {
|
||||
notf(acct, tlid);
|
||||
}
|
||||
$(".notf-icon_" + tlid).removeClass("red-text");
|
||||
}
|
||||
|
||||
//通知オブジェクトパーサー
|
||||
function parseNotf(obj, popup, tlid, acct_id) {
|
||||
var templete = '';
|
||||
var datetype = localStorage.getItem("datetype");
|
||||
var nsfwtype = localStorage.getItem("nsfw");
|
||||
if (!nsfwtype || nsfwtype == "yes") {
|
||||
var nsfw = "ok";
|
||||
} else {
|
||||
var nsfw;
|
||||
}
|
||||
var cwtype = localStorage.getItem("cw");
|
||||
if (!cwtype || cwtype == "yes") {
|
||||
var cw = "ok";
|
||||
} else {
|
||||
var cw;
|
||||
}
|
||||
if (!datetype) {
|
||||
datetype = "absolute";
|
||||
}
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var eachobj = obj[key];
|
||||
var toot = eachobj.status;
|
||||
//トゥートである
|
||||
if (toot) {
|
||||
if (!toot.application) {
|
||||
var via = "<i>Unknown</i>";
|
||||
} else {
|
||||
var via = toot.application.name;
|
||||
}
|
||||
if (toot.account.locked) {
|
||||
var locked = ' <i class="fa fa-lock red-text"></i>';
|
||||
} else {
|
||||
var locked = "";
|
||||
}
|
||||
var id = toot.id;
|
||||
if (eachobj.type == "mention") {
|
||||
var what = "返信しました";
|
||||
} else if (eachobj.type == "reblog") {
|
||||
var what = "ブーストしました";
|
||||
} else if (eachobj.type == "favourite") {
|
||||
var what = "ふぁぼしました";
|
||||
}
|
||||
var noticetext = eachobj.account.display_name + "(" + eachobj.account.acct +
|
||||
")が" + what;
|
||||
if (popup >= 0 && obj.length < 5) {
|
||||
Materialize.toast(noticetext, popup * 1000);
|
||||
$(".notf-icon_" + tlid).addClass("red-text");
|
||||
}
|
||||
if (toot.spoiler_text && cw) {
|
||||
var spoiler = "cw cw_hide_" + toot.id;
|
||||
var spoiler_show = '<a onclick="cw_show(\'' + toot.id + '\')">見る</a>';
|
||||
} else {
|
||||
var spoiler = "";
|
||||
var spoiler_show = "";
|
||||
}
|
||||
var viewer = "";
|
||||
var youtube = "";
|
||||
var mediack = toot.media_attachments[0];
|
||||
if (mediack) {
|
||||
Object.keys(toot.media_attachments).forEach(function(key2) {
|
||||
var media = toot.media_attachments[key2];
|
||||
var purl = media.preview_url;
|
||||
var url = media.url;
|
||||
if (toot.sensitive && nsfw) {
|
||||
var sense = "sensitive"
|
||||
} else {
|
||||
var sense = ""
|
||||
}
|
||||
viewer = viewer + '<a onclick="imgv(\'' + url + '\',\'' + toot.account
|
||||
.acct + '\',\'' + media.type + '\')"><img src="' + purl + '" class="' +
|
||||
sense +
|
||||
'" width="250" style="object-fit: cover; width: 100%; height: 200px;"></a></span>';
|
||||
});
|
||||
} else {
|
||||
viewer = "";
|
||||
}
|
||||
var menck = toot.mentions[0];
|
||||
var mentions = "";
|
||||
if (menck) {
|
||||
mentions = "Links: ";
|
||||
Object.keys(toot.mentions).forEach(function(key3) {
|
||||
var mention = toot.mentions[key3];
|
||||
mentions = mentions + '<a onclick="udg(\'' + mention.id +
|
||||
'\')" class="pointer">@' + mention.acct + '</a> ';
|
||||
});
|
||||
}
|
||||
var tagck = toot.tags[0];
|
||||
var tags = "";
|
||||
if (tagck) {
|
||||
if (!menck) {
|
||||
tags = "Links: ";
|
||||
}
|
||||
Object.keys(toot.tags).forEach(function(key4) {
|
||||
var tag = toot.tags[key4];
|
||||
tags = tags + '<a onclick="tl(\'tag\',\'' + tag.name +
|
||||
'\')" class="pointer">#' + tag.name + '</a> ';
|
||||
});
|
||||
}
|
||||
if (toot.favourited) {
|
||||
var if_fav = " yellow-text";
|
||||
var fav_app = "faved";
|
||||
} else {
|
||||
var if_fav = "";
|
||||
var fav_app = "";
|
||||
}
|
||||
if (toot.reblogged) {
|
||||
var if_rt = "teal-text";
|
||||
var rt_app = "rted";
|
||||
} else {
|
||||
var if_rt = "";
|
||||
var rt_app = "";
|
||||
}
|
||||
if (toot.account.acct == localStorage.getItem("user_" + acct_id)) {
|
||||
var if_mine = "";
|
||||
} else {
|
||||
var if_mine = "hide";
|
||||
}
|
||||
if (toot.favourited) {
|
||||
var if_fav = " yellow-text";
|
||||
var fav_app = "faved";
|
||||
} else {
|
||||
var if_fav = "";
|
||||
var fav_app = "";
|
||||
}
|
||||
if (toot.reblogged) {
|
||||
var if_rt = "teal-text";
|
||||
var rt_app = "rted";
|
||||
} else {
|
||||
var if_rt = "";
|
||||
var rt_app = "";
|
||||
}
|
||||
templete = templete + '<div each=' + toot.datab + ' id="pub_' + toot.id +
|
||||
'" class="cvo ' + fav_app + ' ' + rt_app +
|
||||
'" style="padding-top:5px;" notf-id="' + eachobj.id + '">' +
|
||||
'<span class="gray sharesta">' + noticetext +
|
||||
'<br><span class="cbadge"><i class="fa fa-clock-o"></i>' + date(eachobj.created_at,
|
||||
datetype) + '</span></span>' +
|
||||
'<div style="padding:0; margin:0; width:400px; max-width:100%; display:flex; align-items:flex-end;">' +
|
||||
'<div style="flex-basis:40px;"><a onclick="udg(\'' + toot.account.id +
|
||||
'\',\'' + acct_id + '\');" user="' + toot.account.acct + '" class="udg">' +
|
||||
'<img src="' + toot.account.avatar +
|
||||
'" width="20" class="prof-img" user="' + toot.account.acct +
|
||||
'"></a></div>' +
|
||||
'<div style="flex-grow:3; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;">' +
|
||||
toot.account.display_name + '</div>' +
|
||||
'<div class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"> @' +
|
||||
toot.account.acct + locked + '</div>' +
|
||||
'</div>' +
|
||||
'<span class="toot ' + spoiler + '">' + toot.content +
|
||||
'</span><span class="gray cw_text_' + toot.id + '">' + toot.spoiler_text +
|
||||
spoiler_show + '</span>' +
|
||||
'' + viewer + '' +
|
||||
'<div class="additional"></div><span class="cbadge"><i class="fa fa-clock-o"></i>' +
|
||||
date(toot.created_at, datetype) + '</span>' +
|
||||
'<span class="cbadge">via ' + via + '</span>' + mentions + tags +
|
||||
'<div style="padding:0; margin:0; top:-20px; display:flex; justify-content:space-around; width:500px; max-width:100%; ">' +
|
||||
'<div><a onclick="re(\'' + toot.id + '\',\'' + toot.account.acct + '\',' +
|
||||
acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa fa-share"></i><help>返信</help></a></div>' +
|
||||
'<div><a onclick="rt(\'' + toot.id + '\',' + acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="text-darken-3 fa fa-retweet ' +
|
||||
if_rt + '" id="rt_' + toot.id + '"></i><span class="rt_ct">' + toot.reblogs_count +
|
||||
'</span><help>ブースト</help></a></div>' +
|
||||
'<div><a onclick="fav(\'' + toot.id + '\',' + acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa text-darken-3 fa-star' +
|
||||
if_fav + '" id="fav_' + toot.id + '"></i><span class="fav_ct">' + toot.favourites_count +
|
||||
'<help>お気に入り</help></a></span></div>' +
|
||||
'<div class=' + if_mine + '><a onclick="del(\'' + toot.id + '\',' +
|
||||
acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa fa-trash-o"></i><help>削除</help></a></div>' +
|
||||
'<div><a onclick="details(\'' + toot.id + '\',' + acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat details" style="padding:0"><i class="text-darken-3 material-icons">more_vert</i><help>詳細表示</help></a></div>' +
|
||||
'</div>' +
|
||||
'<div class="divider"></div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
} else if (eachobj.type == "follow") {
|
||||
//フォロー等のユーザーデータである
|
||||
var tooter = eachobj.account;
|
||||
if (tooter.locked) {
|
||||
var locked = ' <i class="fa fa-lock red-text"></i>';
|
||||
} else {
|
||||
var locked = "";
|
||||
}
|
||||
templete = templete +
|
||||
'<div class="cvo " style="padding-top:5px;" notf-id=' + eachobj.id + '>' +
|
||||
'<div style="padding:0; margin:0; width:400px; max-width:100%; display:flex; align-items:flex-end;">' +
|
||||
'<div style="flex-basis:40px;"><a onclick="udg(\'' + tooter.id + '\',\'' +
|
||||
acct_id + '\');" user="' + tooter.acct + '" class="udg">' +
|
||||
'<img src="' + tooter.avatar + '" width="40" class="prof-img" user="' +
|
||||
tooter.acct + '"></a></div>' +
|
||||
'<div style="flex-grow:3; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;">' +
|
||||
tooter.display_name + '<div class="gray sharesta">にフォローされました</div></div>' +
|
||||
'<div class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"> @' +
|
||||
tooter.acct + locked + '</div>' +
|
||||
'</div>' +
|
||||
'<div style="justify-content:space-around"> <div class="cbadge">Follows:' +
|
||||
tooter.following_count + '</div><div class="cbadge">Followers:' + tooter.followers_count +
|
||||
'</div>' +
|
||||
'<div class="divider"></div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
var noticetext = eachobj.account.display_name + "(" + eachobj.account.acct +
|
||||
")がフォローしました";
|
||||
if (popup >= 0 && obj.length < 5) {
|
||||
Materialize.toast(noticetext, popup * 1000);
|
||||
$(".notf-icon").addClass("red-text");
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!noticetext) {
|
||||
var noticetext = null;
|
||||
}
|
||||
return [templete, noticetext];
|
||||
}
|
250
js/tl/parse.js
Normal file
250
js/tl/parse.js
Normal file
@@ -0,0 +1,250 @@
|
||||
//オブジェクトパーサー(トゥート)
|
||||
function parse(obj, mix, acct_id) {
|
||||
var templete = '';
|
||||
var datetype = localStorage.getItem("datetype");
|
||||
var nsfwtype = localStorage.getItem("nsfw");
|
||||
var sent = localStorage.getItem("sentence");
|
||||
if (!sent) {
|
||||
var sent = 500;
|
||||
}
|
||||
if (!nsfwtype || nsfwtype == "yes") {
|
||||
var nsfw = "ok";
|
||||
} else {
|
||||
var nsfw;
|
||||
}
|
||||
var cwtype = localStorage.getItem("cw");
|
||||
if (!cwtype || cwtype == "yes") {
|
||||
var cw = "ok";
|
||||
} else {
|
||||
var cw;
|
||||
}
|
||||
if (!datetype) {
|
||||
datetype = "absolute";
|
||||
}
|
||||
var local = [];
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var toot = obj[key];
|
||||
var id = toot.id;
|
||||
//Integratedである場合はUnix時間をキーに配列を生成しておく
|
||||
if (mix == "mix") {
|
||||
local[date(obj[key].created_at, 'unix')] = toot.id;
|
||||
}
|
||||
if (mix == "home") {
|
||||
var home = "Home TLより"
|
||||
} else {
|
||||
var home = "";
|
||||
}
|
||||
if (toot.reblog) {
|
||||
var notice = toot.account.display_name + "(" + toot.account.acct +
|
||||
")がブースト<br>";
|
||||
var boostback = "shared";
|
||||
var toot = toot.reblog;
|
||||
} else {
|
||||
var notice = "";
|
||||
var boostback = "";
|
||||
}
|
||||
if (toot.account.locked) {
|
||||
var locked = ' <i class="fa fa-lock red-text"></i>';
|
||||
} else {
|
||||
var locked = "";
|
||||
}
|
||||
if (!toot.application) {
|
||||
var via = "<i>Unknown</i>";
|
||||
} else {
|
||||
var via = toot.application.name;
|
||||
}
|
||||
if (toot.spoiler_text && cw) {
|
||||
var content = toot.content;
|
||||
var spoil = toot.spoiler_text;
|
||||
var spoiler = "cw cw_hide_" + toot.id;
|
||||
var api_spoil = "gray";
|
||||
var spoiler_show = '<a href="#" onclick="cw_show(\'' + toot.id +
|
||||
'\')" class="nex parsed">見る</a>';
|
||||
} else {
|
||||
var ct = toot.content.split('</p>').length + toot.content.split('<br />').length -
|
||||
2;
|
||||
if (sent < ct && $.mb_strlen(toot.content) > 5) {
|
||||
var content = '<span class="gray">以下全文</span><br>' + toot.content
|
||||
var spoil = $.strip_tags($.mb_substr(toot.content, 0, 100)) +
|
||||
'<span class="gray">自動折りたたみ</span>';
|
||||
var spoiler = "cw cw_hide_" + toot.id;
|
||||
var spoiler_show = '<a href="#" onclick="cw_show(\'' + toot.id +
|
||||
'\')" class="nex parsed">続き…</a>';
|
||||
} else {
|
||||
var content = toot.content;
|
||||
var spoil = toot.spoiler_text;
|
||||
var spoiler = "";
|
||||
var spoiler_show = "";
|
||||
}
|
||||
}
|
||||
var viewer = "";
|
||||
var youtube = "";
|
||||
var emojick = toot.emojis[0];
|
||||
//絵文字があれば
|
||||
if (emojick) {
|
||||
Object.keys(toot.emojis).forEach(function(key5) {
|
||||
var emoji = toot.emojis[key5];
|
||||
var shortcode = emoji.shortcode;
|
||||
var emoji_url = '<img src="' + emoji.url +
|
||||
'" style="width:2em" class="emoji-img">';
|
||||
var regExp = new RegExp(":" + shortcode + ":", "g");
|
||||
content = content.replace(regExp, emoji_url);
|
||||
});
|
||||
}
|
||||
var mediack = toot.media_attachments[0];
|
||||
//メディアがあれば
|
||||
if (mediack) {
|
||||
Object.keys(toot.media_attachments).forEach(function(key2) {
|
||||
var media = toot.media_attachments[key2];
|
||||
var purl = media.preview_url;
|
||||
var url = media.url;
|
||||
if (toot.sensitive && nsfw) {
|
||||
var sense = "sensitive"
|
||||
} else {
|
||||
var sense = ""
|
||||
}
|
||||
viewer = viewer + '<a onclick="imgv(\''+id+'\',\''+key2+'\')" id="'+id+'-image-'+key2+'" data-url="'+url+'" data-type="'+media.type+'"><img src="' + purl + '" class="' + sense +
|
||||
' toot-img" style=""></a></span>';
|
||||
});
|
||||
} else {
|
||||
viewer = "";
|
||||
}
|
||||
var menck = toot.mentions[0];
|
||||
var mentions = "";
|
||||
//メンションであれば
|
||||
if (menck) {
|
||||
mentions = "Links: ";
|
||||
Object.keys(toot.mentions).forEach(function(key3) {
|
||||
var mention = toot.mentions[key3];
|
||||
mentions = mentions + '<a onclick="udg(\'' + mention.id + '\',' +
|
||||
acct_id + ')" class="pointer">@' + mention.acct + '</a> ';
|
||||
});
|
||||
}
|
||||
var tagck = toot.tags[0];
|
||||
var tags = "";
|
||||
//タグであれば
|
||||
if (tagck) {
|
||||
if (!menck) {
|
||||
tags = "Links: ";
|
||||
}
|
||||
Object.keys(toot.tags).forEach(function(key4) {
|
||||
var tag = toot.tags[key4];
|
||||
tags = tags + '<a onclick="tl(\'tag\',\'' + tag.name + '\',' + acct_id +
|
||||
',\'add\')" class="pointer">#' + tag.name + '</a> ';
|
||||
});
|
||||
}
|
||||
if (toot.account.acct == localStorage.getItem("user_" + acct_id)) {
|
||||
var if_mine = "";
|
||||
} else {
|
||||
var if_mine = "hide";
|
||||
}
|
||||
if (toot.favourited) {
|
||||
var if_fav = " yellow-text";
|
||||
var fav_app = "faved";
|
||||
} else {
|
||||
var if_fav = "";
|
||||
var fav_app = "";
|
||||
}
|
||||
if (toot.reblogged) {
|
||||
var if_rt = "teal-text";
|
||||
var rt_app = "rted";
|
||||
} else {
|
||||
var if_rt = "";
|
||||
var rt_app = "";
|
||||
}
|
||||
templete = templete + '<div id="pub_' + toot.id + '" class="cvo ' +
|
||||
boostback + ' ' + fav_app + ' ' + rt_app +
|
||||
'" style="padding-top:5px;" toot-id="' + id + '" unixtime="' + date(obj[
|
||||
key].created_at, 'unix') + '">' +
|
||||
'<span class="gray sharesta">' + notice + home + '</span>' +
|
||||
'<div style="padding:0; margin:0; width:400px; max-width:100%; display:flex; align-items:flex-end;">' +
|
||||
'<div style="flex-basis:40px;"><a onclick="udg(\'' + toot.account.id +
|
||||
'\',' + acct_id + ');" user="' + toot.account.acct + '" class="udg">' +
|
||||
'<img src="' + toot.account.avatar +
|
||||
'" width="40" class="prof-img" user="' + toot.account.acct +
|
||||
'"></a></div>' +
|
||||
'<div style="flex-grow:3; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"><big>' +
|
||||
toot.account.display_name + '</big></div>' +
|
||||
'<div class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"> @' +
|
||||
toot.account.acct + locked + '</div>' +
|
||||
'</div>' +
|
||||
'<div style="display:none; justify-content:space-around" class="sml gray"> <div>Follows:' +
|
||||
toot.account.following_count + '</div><div>Followers:' + toot.account.followers_count +
|
||||
'</div>' +
|
||||
'<div>Toots:' + toot.account.statuses_count + '</div></div>' +
|
||||
'<span class="toot ' + spoiler + '">' + content + '</span><span class="' +
|
||||
api_spoil + ' cw_text_' + toot.id + '">' + spoil + spoiler_show +
|
||||
'</span>' +
|
||||
'' + viewer + '' +
|
||||
'<div class="additional"></div><span class="cbadge"><i class="fa fa-clock-o"></i>' +
|
||||
date(toot.created_at, datetype) + '</span>' +
|
||||
'<span class="cbadge">via ' + via +
|
||||
'<help class="white-text">どこから投稿したか</help></span>' + mentions + tags +
|
||||
'<div style="padding:0; margin:0; top:-20px; display:flex; justify-content:space-around; width:500px; max-width:100%; ">' +
|
||||
'<div><a onclick="re(\'' + toot.id + '\',\'' + toot.account.acct + '\',' +
|
||||
acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa fa-share"></i></a></div>' +
|
||||
'<div><a onclick="rt(\'' + toot.id + '\',' + acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="text-darken-3 fa fa-retweet ' +
|
||||
if_rt + '" id="rt_' + toot.id + '"></i><span class="rt_ct">' + toot.reblogs_count +
|
||||
'</span></a></div>' +
|
||||
'<div><a onclick="fav(\'' + toot.id + '\',' + acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa text-darken-3 fa-star' +
|
||||
if_fav + '" id="fav_' + toot.id + '"></i><span class="fav_ct">' + toot.favourites_count +
|
||||
'</a></span></div>' +
|
||||
'<div class=' + if_mine + '><a onclick="del(\'' + toot.id + '\',' +
|
||||
acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa fa-trash-o"></i></a></div>' +
|
||||
'<div><a onclick="details(\'' + toot.id + '\',' + acct_id +
|
||||
')" class="waves-effect waves-dark btn-flat details" style="padding:0"><i class="text-darken-3 material-icons">more_vert</i></a></div>' +
|
||||
'</div>' +
|
||||
'<div class="divider"></div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
});
|
||||
if (mix == "mix") {
|
||||
return [templete, local]
|
||||
} else {
|
||||
return templete;
|
||||
}
|
||||
}
|
||||
|
||||
//オブジェクトパーサー(ユーザーデータ)
|
||||
function userparse(obj, auth) {
|
||||
var templete = '';
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var toot = obj[key];
|
||||
if (toot.locked) {
|
||||
var locked = ' <i class="fa fa-lock red-text"></i>';
|
||||
} else {
|
||||
var locked = "";
|
||||
}
|
||||
if (auth) {
|
||||
var auth = '<i class="material-icons gray pointer" onclick="request(\'' +
|
||||
toot.id + '\',\'authorize\',' + acct_id + ')">person_add</i>';
|
||||
} else {
|
||||
var auth = "";
|
||||
}
|
||||
templete = templete +
|
||||
'<div class="cvo " style="padding-top:5px;" user-id="' + toot.id + '">' +
|
||||
'<div style="padding:0; margin:0; width:400px; max-width:100%; display:flex; align-items:flex-end;">' +
|
||||
'<div style="flex-basis:40px;"><a onclick="udg(\'' + toot.id + '\',' +
|
||||
acct_id + ');" user="' + toot.acct + '" class="udg">' +
|
||||
'<img src="' + toot.avatar + '" width="40" class="prof-img" user="' + toot
|
||||
.acct + '"></a></div>' +
|
||||
'<div style="flex-grow:3; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"><big>' +
|
||||
toot.display_name + '</big></div>' +
|
||||
'<div class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;"> @' +
|
||||
toot.acct + locked + '</div>' +
|
||||
'</div>' + auth +
|
||||
'<div style="justify-content:space-around"> <div class="cbadge">Follows:' +
|
||||
toot.following_count + '</div><div class="cbadge">Followers:' + toot.followers_count +
|
||||
'</div>' +
|
||||
'<div class="divider"></div>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
});
|
||||
return templete;
|
||||
}
|
55
js/tl/src.js
Normal file
55
js/tl/src.js
Normal file
@@ -0,0 +1,55 @@
|
||||
//検索
|
||||
//検索ボックストグル
|
||||
function srcToggle() {
|
||||
$("#src-box").toggleClass("hide");
|
||||
$('ul.tabs').tabs('select_tab', 'src-sta');
|
||||
$("#src-contents").html("");
|
||||
}
|
||||
|
||||
//検索取得
|
||||
function src() {
|
||||
var q = $("#src").val();
|
||||
var acct_id = $("#src-acct-sel").val();
|
||||
localStorage.setItem("last-use", acct_id);
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (user == "--now") {
|
||||
var user = $('#his-data').attr("user-id");
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/search?q=" + q
|
||||
console.log(start)
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
//トゥート
|
||||
if (json.statuses[0]) {
|
||||
var templete = parse(json.statuses);
|
||||
$("#src-contents").append("Mentions<br>" + templete);
|
||||
}
|
||||
//アカウント
|
||||
if (json.accounts[0]) {
|
||||
var templete = userparse(json.accounts);
|
||||
$("#src-contents").append("Accounts<br>" + templete);
|
||||
}
|
||||
//ハッシュタグ
|
||||
if (json.hashtags[0]) {
|
||||
var tags = "";
|
||||
Object.keys(json.hashtags).forEach(function(key4) {
|
||||
var tag = json.hashtags[key4];
|
||||
tags = tags + '<a onclick="tl(\'tag\',\'' + tag + '\',\'' + acct_id +
|
||||
'\',\'add\')" class="pointer">#' + tag + '</a><br> ';
|
||||
});
|
||||
$("#src-contents").append("Tags<br>" + tags);
|
||||
}
|
||||
jQuery("time.timeago").timeago();
|
||||
});
|
||||
}
|
240
js/tl/tl.js
Normal file
240
js/tl/tl.js
Normal file
@@ -0,0 +1,240 @@
|
||||
//TL取得
|
||||
function tl(type, data, acct_id, tlid) {
|
||||
scrollevent();
|
||||
localStorage.removeItem("morelock");
|
||||
localStorage.removeItem("pool");
|
||||
//タグの場合はカラム追加して描画
|
||||
if (tlid == "add") {
|
||||
console.log("add");
|
||||
var newtab = $(".box").length;
|
||||
var add = {
|
||||
domain: acct_id,
|
||||
type: "tag",
|
||||
data: data
|
||||
};
|
||||
var multi = localStorage.getItem("column");
|
||||
var obj = JSON.parse(multi);
|
||||
obj.push(add);
|
||||
console.log(obj);
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("column", json);
|
||||
parseColumn();
|
||||
return;
|
||||
}
|
||||
if (!type) {
|
||||
var type = localStorage.getItem("now");
|
||||
if (!type) {
|
||||
//デフォルト
|
||||
var type = "local";
|
||||
}
|
||||
}
|
||||
if (type == "mix") {
|
||||
//Integratedなら飛ばす
|
||||
mixtl(acct_id, tlid);
|
||||
return;
|
||||
} else if (type == "notf") {
|
||||
//通知なら飛ばす
|
||||
notf(acct_id, tlid, 'direct');
|
||||
$("#notice_" + tlid).text(cap(type, data) + " TL(" + localStorage.getItem(
|
||||
"user_" + acct_id) + "@" + domain + ")");
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("now", type);
|
||||
todo(cap(type) + " TL Loading...");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
$("#notice_" + tlid).text(cap(type, data) + " TL(" + localStorage.getItem(
|
||||
"user_" + acct_id) + "@" + domain + ")");
|
||||
var start = "https://" + domain + "/api/v1/timelines/" + com(type, data);
|
||||
console.log(start);
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json, '', acct_id);
|
||||
$("#timeline_" + tlid).html(templete);
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
todc();
|
||||
reload(type, '', acct_id, tlid);
|
||||
$(window).scrollTop(0);
|
||||
});
|
||||
}
|
||||
|
||||
//Streaming接続
|
||||
function reload(type, cc, acct_id, tlid) {
|
||||
if (!type) {
|
||||
var type = localStorage.getItem("now");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
localStorage.setItem("now", type);
|
||||
if (type == "home") {
|
||||
var start = "wss://" + domain +
|
||||
"/api/v1/streaming/?stream=user&access_token=" + at;
|
||||
} else if (type == "pub") {
|
||||
var start = "wss://" + domain +
|
||||
"/api/v1/streaming/?stream=public&access_token=" + at;
|
||||
} else if (type == "local") {
|
||||
var start = "wss://" + domain +
|
||||
"/api/v1/streaming/?stream=public:local&access_token=" + at;
|
||||
}
|
||||
console.log(start);
|
||||
var wsid = websocket.length;
|
||||
websocket[wsid] = new WebSocket(start);
|
||||
websocket[wsid].onopen = function(mess) {
|
||||
console.log(tlid + ":Connect Streaming API:" + type);
|
||||
console.log(mess);
|
||||
}
|
||||
websocket[wsid].onmessage = function(mess) {
|
||||
console.log(tlid + ":Receive Streaming API:");
|
||||
console.log(websocket[wsid]);
|
||||
|
||||
|
||||
var typeA = JSON.parse(mess.data).event;
|
||||
if (typeA == "delete") {
|
||||
var obj = JSON.parse(mess.data).payload;
|
||||
$("[toot-id=" + obj + "]").hide();
|
||||
} else if (typeA == "update") {
|
||||
var obj = JSON.parse(JSON.parse(mess.data).payload);
|
||||
console.log(obj);
|
||||
var templete = parse([obj], '', acct_id);
|
||||
var pool = localStorage.getItem("pool_" + tlid);
|
||||
if (pool) {
|
||||
pool = templete + pool;
|
||||
} else {
|
||||
pool = templete
|
||||
}
|
||||
localStorage.setItem("pool_" + tlid, pool);
|
||||
|
||||
scrollck();
|
||||
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
todc();
|
||||
}
|
||||
websocket[wsid].onclose = function(mess) {
|
||||
console.log("Close Streaming API:" + type);
|
||||
}
|
||||
}
|
||||
websocket[wsid].onerror = function(error) {
|
||||
console.error('WebSocket Error ' + error);
|
||||
};
|
||||
}
|
||||
|
||||
//一定のスクロールで発火
|
||||
function moreload(type, tlid) {
|
||||
var multi = localStorage.getItem("column");
|
||||
var obj = JSON.parse(multi);
|
||||
var acct_id = obj[tlid].domain;
|
||||
if (!type) {
|
||||
var type = localStorage.getItem("now");
|
||||
}
|
||||
var sid = $("#timeline_" + tlid + " .cvo").last().attr("toot-id");
|
||||
console.log(localStorage.getItem("morelock") + ":" + sid)
|
||||
if (localStorage.getItem("morelock") != sid) {
|
||||
localStorage.setItem("morelock", sid);
|
||||
if (type == "mix") {
|
||||
mixmore();
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("now", type);
|
||||
todo(cap(type) + " TL MoreLoading");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/timelines/" + com(type) +
|
||||
"max_id=" + sid;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json, '', acct_id);
|
||||
$("#timeline_" + tlid).append(templete);
|
||||
additional(acct_id, tlid);
|
||||
jQuery("time.timeago").timeago();
|
||||
todc();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//WebSocket切断
|
||||
function tlCloser() {
|
||||
Object.keys(websocket).forEach(function(tlid) {
|
||||
if (websocketOld[tlid]) {
|
||||
websocketOld[tlid].close();
|
||||
console.log("Close Streaming API: Old" + tlid);
|
||||
}
|
||||
if (websocket[0]) {
|
||||
console.log(websocket[0]);
|
||||
websocket[tlid].close();
|
||||
console.log("Close Streaming API:" + tlid);
|
||||
}
|
||||
|
||||
});
|
||||
websocket = [];
|
||||
Object.keys(websocketHome).forEach(function(tlid) {
|
||||
if (websocketHome[tlid]) {
|
||||
websocketHome[tlid].close();
|
||||
console.log("Close Streaming API:MixHome" + tlid);
|
||||
}
|
||||
|
||||
});
|
||||
websocketHome = [];
|
||||
Object.keys(websocketLocal).forEach(function(tlid) {
|
||||
if (websocketLocal[tlid]) {
|
||||
websocketLocal[tlid].close();
|
||||
console.log("Close Streaming API:MixLocal" + tlid);
|
||||
}
|
||||
|
||||
});
|
||||
websocketLocal = [];
|
||||
}
|
||||
|
||||
//TLのタイトル
|
||||
function cap(type, data) {
|
||||
if (type == "home") {
|
||||
return "Home"
|
||||
} else if (type == "local") {
|
||||
return "Local"
|
||||
} else if (type == "pub") {
|
||||
return "Public"
|
||||
} else if (type == "tag") {
|
||||
return "#" + data
|
||||
} else if (type == "list") {
|
||||
return "List(id:" + data + ")"
|
||||
} else if (type == "notf") {
|
||||
return "Notification"
|
||||
}
|
||||
}
|
||||
|
||||
//TLのURL
|
||||
function com(type, data) {
|
||||
if (type == "home") {
|
||||
return "home?"
|
||||
} else if (type == "local") {
|
||||
return "public?local=true&"
|
||||
} else if (type == "pub") {
|
||||
return "public?"
|
||||
} else if (type == "tag") {
|
||||
return "tag/" + data + "?"
|
||||
}
|
||||
if (type == "list") {
|
||||
return "list/" + data + "?"
|
||||
}
|
||||
}
|
162
js/ui/img.js
Normal file
162
js/ui/img.js
Normal file
@@ -0,0 +1,162 @@
|
||||
/*イメージビューワー*/
|
||||
//postのimg.jsとは異なります。
|
||||
function imgv(id, key) {
|
||||
$('#imgmodal').attr('src', './img/loading.svg');
|
||||
var murl = $("#" + id + "-image-" + key).attr("data-url");
|
||||
var type = $("#" + id + "-image-" + key).attr("data-type");
|
||||
$(document).ready(function() {
|
||||
if (type == "image") {
|
||||
$('#imgmodal').attr('src', murl);
|
||||
$('#imagewrap').dragScroll(); // ドラッグスクロール設定
|
||||
$('#imagemodal').modal('open');
|
||||
$('#imagemodal').attr('data-key', key);
|
||||
$('#imagemodal').attr('data-id', id);
|
||||
} else if (type == "video" || type == "gifv") {
|
||||
$('#video').attr('src', murl);
|
||||
$('#videomodal').modal('open');
|
||||
}
|
||||
var element = new Image();
|
||||
var width;
|
||||
element.onload = function() {
|
||||
var width = element.naturalWidth;
|
||||
var height = element.naturalHeight;
|
||||
$("#imgmodal").attr('width', width);
|
||||
$("#imagemodal").css('height', "calc(100vh - 20px)");
|
||||
}
|
||||
if ($("#" + id + "-image-" + (key * 1 + 1)).length == 0) {
|
||||
$("#image-next").prop("disabled", true);
|
||||
}
|
||||
if ($("#" + id + "-image-" + (key * 1 - 1)).length == 0) {
|
||||
$("#image-prev").prop("disabled", true);
|
||||
}
|
||||
element.src = murl;
|
||||
});
|
||||
}
|
||||
//イメージビューワーの送り
|
||||
function imgCont(type) {
|
||||
var key = $('#imagemodal').attr('data-key');
|
||||
var id = $('#imagemodal').attr('data-id');
|
||||
|
||||
if (type == "next") {
|
||||
key++;
|
||||
} else if (type == "prev") {
|
||||
key = key * 1 - 1;
|
||||
}
|
||||
$('#imgmodal').attr('src', './img/loading.svg');
|
||||
var murl = $("#" + id + "-image-" + key).attr("data-url");
|
||||
var type = $("#" + id + "-image-" + key).attr("data-type");
|
||||
$(document).ready(function() {
|
||||
if (type == "image") {
|
||||
$('#imgmodal').attr('src', murl);
|
||||
$('#imagewrap').dragScroll(); // ドラッグスクロール設定
|
||||
$('#imagemodal').attr('data-key', key);
|
||||
$('#imagemodal').attr('data-id', id);
|
||||
} else if (type == "video" || type == "gifv") {
|
||||
$('#video').attr('src', murl);
|
||||
$('#videomodal').modal('open');
|
||||
}
|
||||
var element = new Image();
|
||||
var width;
|
||||
element.onload = function() {
|
||||
var width = element.naturalWidth;
|
||||
var height = element.naturalHeight;
|
||||
$("#imgmodal").attr('width', width);
|
||||
$("#imagemodal").css('height', "calc(100vh - 20px)");
|
||||
}
|
||||
if ($("#" + id + "-image-" + (key * 1 + 1)).length == 0) {
|
||||
$("#image-next").prop("disabled", true);
|
||||
} else {
|
||||
$("#image-next").prop("disabled", false);
|
||||
}
|
||||
console.log("#" + id + "-image-" + (key * 1 - 1));
|
||||
if ($("#" + id + "-image-" + (key * 1 - 1)).length == 0) {
|
||||
$("#image-prev").prop("disabled", true);
|
||||
} else {
|
||||
$("#image-prev").prop("disabled", false);
|
||||
}
|
||||
element.src = murl;
|
||||
});
|
||||
}
|
||||
//ズームボタン(z:倍率)
|
||||
function zoom(z) {
|
||||
var wdth = $('#imagewrap img').width();
|
||||
var wdth = wdth * z;
|
||||
$('#imagewrap img').attr("width", wdth);
|
||||
}
|
||||
//スマホ対応ドラッグ移動システム
|
||||
(function() {
|
||||
$.fn.dragScroll = function() {
|
||||
var target = this;
|
||||
$(this).mousedown(function(event) {
|
||||
$(this)
|
||||
.data('down', true)
|
||||
.data('x', event.clientX)
|
||||
.data('y', event.clientY)
|
||||
.data('scrollLeft', this.scrollLeft)
|
||||
.data('scrollTop', this.scrollTop);
|
||||
return false;
|
||||
}).css({
|
||||
'overflow': 'hidden', // スクロールバー非表示
|
||||
'cursor': 'move'
|
||||
});
|
||||
// ウィンドウから外れてもイベント実行
|
||||
$(document).mousemove(function(event) {
|
||||
if ($(target).data('down') == true) {
|
||||
// スクロール
|
||||
target.scrollLeft($(target).data('scrollLeft') + $(target).data('x') -
|
||||
event.clientX);
|
||||
target.scrollTop($(target).data('scrollTop') + $(target).data('y') -
|
||||
event.clientY);
|
||||
return false; // 文字列選択を抑止
|
||||
}
|
||||
}).mouseup(function(event) {
|
||||
$(target).data('down', false);
|
||||
});
|
||||
$(this).on('touchstart', function(event) {
|
||||
$(this)
|
||||
.data('down', true)
|
||||
.data('x', getX(event))
|
||||
.data('y', getY(event))
|
||||
.data('scrollLeft', this.scrollLeft)
|
||||
.data('scrollTop', this.scrollTop);
|
||||
return false;
|
||||
}).css({
|
||||
'overflow': 'hidden', // スクロールバー非表示
|
||||
'cursor': 'move'
|
||||
}); //指が触れたか検知
|
||||
$(this).on('touchmove', function(event) {
|
||||
if ($(target).data('down') == true) {
|
||||
// スクロール
|
||||
console.log($(target).data('x'));
|
||||
target.scrollLeft($(target).data('scrollLeft') + $(target).data('x') -
|
||||
getX(event));
|
||||
target.scrollTop($(target).data('scrollTop') + $(target).data('y') -
|
||||
getY(event));
|
||||
return false; // 文字列選択を抑止
|
||||
} else {}
|
||||
}); //指が動いたか検知
|
||||
$(this).on('touchend', function(event) {
|
||||
$(target).data('down', false);
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
})(jQuery);
|
||||
|
||||
function getX(event) {
|
||||
return event.originalEvent.touches[0].pageX;
|
||||
}
|
||||
|
||||
function getY(event) {
|
||||
return event.originalEvent.touches[0].pageY;
|
||||
}
|
||||
//マウスホイールで拡大
|
||||
var element = document.getElementById("imagemodal");
|
||||
element.onmousewheel = function(e) {
|
||||
var delta = e.wheelDelta;
|
||||
if (delta > 0) {
|
||||
zoom(1.1)
|
||||
} else {
|
||||
zoom(0.9)
|
||||
}
|
||||
}
|
133
js/ui/layout.js
Normal file
133
js/ui/layout.js
Normal file
@@ -0,0 +1,133 @@
|
||||
//レイアウトの設定
|
||||
|
||||
var websocketOld = [];
|
||||
var websocket = [];
|
||||
var websocketHome = [];
|
||||
var websocketLocal = [];
|
||||
|
||||
//カラム追加ボックストグル
|
||||
function addToggle() {
|
||||
$("#add-box").toggleClass("hide");
|
||||
}
|
||||
//最初、カラム変更時に発火
|
||||
function parseColumn() {
|
||||
var multi = localStorage.getItem("multi");
|
||||
if (!multi) {
|
||||
var obj = [{
|
||||
at: localStorage.getItem(localStorage.getItem("domain_0") + "_at"),
|
||||
name: localStorage.getItem("name_0"),
|
||||
domain: localStorage.getItem("domain_0"),
|
||||
user: localStorage.getItem("user_0"),
|
||||
prof: localStorage.getItem("prof_0")
|
||||
}];
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("multi", json);
|
||||
} else {
|
||||
var obj = JSON.parse(multi);
|
||||
|
||||
var templete;
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var acct = obj[key];
|
||||
localStorage.setItem("name_" + key, acct.name);
|
||||
localStorage.setItem("user_" + key, acct.user);
|
||||
localStorage.setItem("user-id_" + key, acct.user);
|
||||
localStorage.setItem("prof_" + key, acct.prof);
|
||||
localStorage.setItem("domain_" + key, acct.domain);
|
||||
localStorage.setItem(acct.domain + "_at", acct.at);
|
||||
});
|
||||
}
|
||||
var col = localStorage.getItem("column");
|
||||
if (!col) {
|
||||
var obj = [{
|
||||
domain: 0,
|
||||
type: 'local'
|
||||
}];
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("column", json);
|
||||
} else {
|
||||
var obj = JSON.parse(col);
|
||||
}
|
||||
if ($("#timeline-container").length) {
|
||||
$("#timeline-container").html("");
|
||||
}
|
||||
tlCloser();
|
||||
Object.keys(obj).forEach(function(key) {
|
||||
var acct = obj[key];
|
||||
var html = '<div class="box" id="timeline_' + key + '_box" tlid="' + key +
|
||||
'"><div><span id="notice_' + key + '" class="notice"></span>' +
|
||||
'<a onclick="notfToggle(' + acct.domain + ',' + key +
|
||||
')" class="setting nex" title="このアカウントの通知"><i class="material-icons nex notf-icon_' +
|
||||
key + '">notifications</i></a>' +
|
||||
'<a onclick="removeColumn(' + key +
|
||||
')" class="setting nex"><i class="material-icons nex" title="このカラムを削除">remove_circle</i></a>' +
|
||||
'<a onclick="cardToggle(' + key +
|
||||
')" class="setting nex"><i class="material-icons nex" title="リンクの解析を切り替え(OFFで制限を回避出来る場合があります)">link</i><span id="sta-card-' +
|
||||
key + '">On</span></a>' +
|
||||
'<div class="hide notf-indv-box" id="notf-box_' + key +
|
||||
'"><div id="notifications_' + key +
|
||||
'"></div></div></div><div id="timeline_' + key +
|
||||
'" class="tl"></div></div>';
|
||||
$("#timeline-container").append(html);
|
||||
if (acct.data) {
|
||||
var data = acct.data;
|
||||
} else {
|
||||
var data = "";
|
||||
}
|
||||
tl(acct.type, data, acct.domain, key);
|
||||
|
||||
cardCheck(key);
|
||||
});
|
||||
var width = localStorage.getItem("width");
|
||||
if (width) {
|
||||
$(".box").css("min-width", width + "px");
|
||||
}
|
||||
var box = localStorage.getItem("box");
|
||||
if (box == "yes") {
|
||||
$("#post-box").addClass("hidenbox");
|
||||
$("#post-box").fadeOut();
|
||||
$("#menu-btn").fadeIn();
|
||||
}
|
||||
var vis = localStorage.getItem("vis");
|
||||
if (!vis) {
|
||||
$("#vis").text("public");
|
||||
} else {
|
||||
if (vis == "memory") {
|
||||
var memory = localStorage.getItem("vis-memory");
|
||||
if (!memory) {
|
||||
memory = "public";
|
||||
}
|
||||
$("#vis").text(memory);
|
||||
} else {
|
||||
$("#vis").text(vis);
|
||||
}
|
||||
}
|
||||
}
|
||||
//カラム追加
|
||||
function addColumn() {
|
||||
var acct = $("#add-acct-sel").val();
|
||||
localStorage.setItem("last-use", acct);
|
||||
var type = $("#type-sel").val();
|
||||
var add = {
|
||||
domain: acct,
|
||||
type: type
|
||||
};
|
||||
var multi = localStorage.getItem("column");
|
||||
var obj = JSON.parse(multi);
|
||||
obj.push(add);
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("column", json);
|
||||
parseColumn();
|
||||
}
|
||||
//カラム削除
|
||||
function removeColumn(tlid) {
|
||||
var multi = localStorage.getItem("column");
|
||||
var obj = JSON.parse(multi);
|
||||
//聞く
|
||||
if (confirm("このコラムを削除します")) {
|
||||
localStorage.removeItem("card_" + tlid);
|
||||
obj.splice(tlid, 1);
|
||||
var json = JSON.stringify(obj);
|
||||
localStorage.setItem("column", json);
|
||||
parseColumn();
|
||||
}
|
||||
}
|
36
js/ui/post-box.js
Normal file
36
js/ui/post-box.js
Normal file
@@ -0,0 +1,36 @@
|
||||
/*ささやきボックス(Cr民並感)*/
|
||||
//もっとボタン
|
||||
function more() {
|
||||
$(".more-show").show();
|
||||
$(".more-hide").hide();
|
||||
$("#post-box").addClass("post-more");
|
||||
}
|
||||
//閉じるボタン
|
||||
function less() {
|
||||
$(".more-show").hide();
|
||||
$(".more-hide").show();
|
||||
$("#post-box").removeClass("post-more");
|
||||
}
|
||||
//✕隠す
|
||||
function hide() {
|
||||
$("#post-box").addClass("hidenbox");
|
||||
$("#post-box").fadeOut();
|
||||
$("#menu-btn").fadeIn();
|
||||
}
|
||||
//最小化時に展開
|
||||
function show() {
|
||||
$("#post-box").removeClass("hidenbox");
|
||||
$("#post-box").fadeIn();
|
||||
$("#menu-btn").fadeOut();
|
||||
}
|
||||
//横幅
|
||||
function zoomBox() {
|
||||
if ($("#post-box").hasClass("bigbox")) {
|
||||
$("#post-box").css('width', '350px');
|
||||
$("#post-box").removeClass("bigbox")
|
||||
} else {
|
||||
$("#post-box").css('width', '50vw');
|
||||
$("#post-box").addClass("bigbox")
|
||||
}
|
||||
|
||||
}
|
28
js/ui/scroll.js
Normal file
28
js/ui/scroll.js
Normal file
@@ -0,0 +1,28 @@
|
||||
//スクロールで続きを読む
|
||||
function scrollevent() {
|
||||
$(".box").scroll(function() {
|
||||
scrollck();
|
||||
});
|
||||
}
|
||||
scrollevent();
|
||||
|
||||
function scrollck() {
|
||||
$(".box").each(function(i, elem) {
|
||||
var tlid = $(this).attr('tlid');
|
||||
//一番上ならためていた新しいトゥートを表示
|
||||
if ($(this).scrollTop() == 0) {
|
||||
var pool = localStorage.getItem("pool_" + tlid);
|
||||
if (pool) {
|
||||
$("#timeline_" + tlid).prepend(pool);
|
||||
jQuery("time.timeago").timeago();
|
||||
localStorage.removeItem("pool_" + tlid);
|
||||
}
|
||||
}
|
||||
//続きを読むトリガー
|
||||
var scrt = $(this).find(".tl").height() - 1000;
|
||||
var scr = $(this).scrollTop();
|
||||
if (scr > scrt) {
|
||||
moreload('', tlid);
|
||||
}
|
||||
});
|
||||
}
|
136
js/ui/settings.js
Normal file
136
js/ui/settings.js
Normal file
@@ -0,0 +1,136 @@
|
||||
//設定(setting.html)で読む
|
||||
//設定ボタン押した。
|
||||
function settings() {
|
||||
var dd = $("[name=time]:checked").val();
|
||||
if (dd != localStorage.getItem("datetype")) {
|
||||
Materialize.toast("時間設定を" + dd + "に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("datetype", dd);
|
||||
var cd = $("[name=theme]:checked").val();
|
||||
if (cd != localStorage.getItem("theme")) {
|
||||
Materialize.toast("テーマ設定を" + cd + "に設定しました。", 3000);
|
||||
}
|
||||
//テーマはこの場で設定
|
||||
themes(cd);
|
||||
localStorage.setItem("theme", cd);
|
||||
var nd = $("[name=nsfw]:checked").val();
|
||||
if (nd != localStorage.getItem("nsfw")) {
|
||||
Materialize.toast("画像表示設定を" + nd + "に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("nsfw", nd);
|
||||
var cwd = $("[name=cw]:checked").val();
|
||||
if (cwd != localStorage.getItem("cw")) {
|
||||
Materialize.toast("テキスト表示設定を" + cwd + "に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("cw", cwd);
|
||||
var cwtd = $("#cw-text").val();
|
||||
if (cwtd != localStorage.getItem("cw-text")) {
|
||||
Materialize.toast("デフォルトの警告文を「" + cwtd + "」に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("cw-text", cwtd);
|
||||
var visd = $("[name=vis]:checked").val();
|
||||
if (visd != localStorage.getItem("vis")) {
|
||||
Materialize.toast("デフォルトの公開設定を" + visd + "に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("vis", visd);
|
||||
var popd = $("#popup").val();
|
||||
if (popd > 0 && popd != localStorage.getItem("popup")) {
|
||||
Materialize.toast("ポップアップお知らせを" + popd + "秒に設定しました。", 3000);
|
||||
} else if (popd != localStorage.getItem("popup")) {
|
||||
Materialize.toast("ポップアップお知らせをオフに設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("popup", popd);
|
||||
var boxd = $("[name=box]:checked").val();
|
||||
if (boxd != localStorage.getItem("box")) {
|
||||
Materialize.toast("デフォルトでボックスを隠すかを" + boxd + "に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("box", boxd);
|
||||
var sentd = $("#sentence").val();
|
||||
if (sentd != localStorage.getItem("sentence")) {
|
||||
Materialize.toast("指定行超過折りたたみを" + sentd + "行に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("sentence", sentd);
|
||||
var widthd = $("#width").val();
|
||||
if (widthd != localStorage.getItem("width")) {
|
||||
Materialize.toast("横幅最低を" + widthd + "pxに設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("width", widthd);
|
||||
var imgd = $("[name=img]:checked").val();
|
||||
if (imgd != localStorage.getItem("img")) {
|
||||
Materialize.toast("画像投稿後の設定を" + imgd + "に設定しました。", 3000);
|
||||
}
|
||||
localStorage.setItem("img", imgd);
|
||||
}
|
||||
|
||||
//読み込み時の設定ロード
|
||||
function load() {
|
||||
var prof = localStorage.getItem("prof");
|
||||
$("#my-prof").attr("src", prof);
|
||||
var datetype = localStorage.getItem("datetype");
|
||||
if (!datetype) {
|
||||
var datetype = "absolute";
|
||||
}
|
||||
$("#" + datetype).prop("checked", true);
|
||||
|
||||
var theme = localStorage.getItem("theme");
|
||||
if (!theme) {
|
||||
var theme = "white";
|
||||
}
|
||||
$("#" + theme).prop("checked", true);
|
||||
|
||||
var nsfw = localStorage.getItem("nsfw");
|
||||
if (!nsfw) {
|
||||
var nsfw = "yes";
|
||||
}
|
||||
$("#n_" + nsfw).prop("checked", true);
|
||||
|
||||
var cw = localStorage.getItem("cw");
|
||||
if (!cw) {
|
||||
var cw = "yes";
|
||||
}
|
||||
$("#c_" + cw).prop("checked", true);
|
||||
|
||||
var popup = localStorage.getItem("popup");
|
||||
if (!popup) {
|
||||
var popup = "0";
|
||||
}
|
||||
$("#popup").val(popup);
|
||||
|
||||
var box = localStorage.getItem("box");
|
||||
if (!box) {
|
||||
var box = "no";
|
||||
}
|
||||
$("#b_" + box).prop("checked", true);
|
||||
|
||||
var sent = localStorage.getItem("sentence");
|
||||
if (!sent) {
|
||||
var sent = "500";
|
||||
}
|
||||
$("#sentence").val(sent);
|
||||
|
||||
var width = localStorage.getItem("width");
|
||||
if (!width) {
|
||||
var width = "300";
|
||||
}
|
||||
$("#width").val(width);
|
||||
|
||||
var cwt = localStorage.getItem("cw-text");
|
||||
if (!cwt) {
|
||||
var cwt = "";
|
||||
}
|
||||
$("#cw-text").val(cwt);
|
||||
|
||||
var vis = localStorage.getItem("vis");
|
||||
if (!vis) {
|
||||
var vis = "public";
|
||||
}
|
||||
$("#" + vis).prop("checked", true);
|
||||
|
||||
var img = localStorage.getItem("img");
|
||||
if (!img) {
|
||||
var img = "no-act";
|
||||
}
|
||||
$("#i_" + img).prop("checked", true);
|
||||
}
|
||||
//最初に読む
|
||||
load();
|
12
js/ui/theme.js
Normal file
12
js/ui/theme.js
Normal file
@@ -0,0 +1,12 @@
|
||||
//テーマ適用
|
||||
function themes(theme) {
|
||||
if (!theme) {
|
||||
var theme = localStorage.getItem("theme");
|
||||
}
|
||||
if (theme == "black") {
|
||||
$("html").addClass("blacktheme");
|
||||
} else {
|
||||
$("html").removeClass("blacktheme");
|
||||
}
|
||||
}
|
||||
themes();
|
8
js/ui/tips.js
Normal file
8
js/ui/tips.js
Normal file
@@ -0,0 +1,8 @@
|
||||
//左下のメッセージ
|
||||
function todo(mes){
|
||||
$('#message').text(mes);
|
||||
$('#message').fadeIn();
|
||||
}
|
||||
function todc(){
|
||||
$('#message').fadeOut();
|
||||
}
|
322
js/userdata/his-data.js
Normal file
322
js/userdata/his-data.js
Normal file
@@ -0,0 +1,322 @@
|
||||
//ユーザーデータ表示
|
||||
//タイムライン
|
||||
function utl(user, more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (user == "--now") {
|
||||
var user = $('#his-data').attr("user-id");
|
||||
}
|
||||
if (more) {
|
||||
var sid = $("#his-tl .cvo").last().attr("toot-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + user + "/statuses" +
|
||||
plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json, '', acct_id);
|
||||
var height = $("#his-data-content").height() - 245;
|
||||
$(".tab-content").css('height', height);
|
||||
if (more) {
|
||||
$("#his-tl-contents").append(templete);
|
||||
} else {
|
||||
$("#his-tl-contents").html(templete);
|
||||
}
|
||||
jQuery("time.timeago").timeago();
|
||||
});
|
||||
}
|
||||
|
||||
//フォローリスト
|
||||
function flw(user, more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (user == "--now") {
|
||||
var user = $('#his-data').attr("user-id");
|
||||
}
|
||||
if (more) {
|
||||
var sid = $("#his-follow-list .cvo").last().attr("user-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + user + "/following" +
|
||||
plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json);
|
||||
if (more) {
|
||||
$("#his-follow-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-follow-list-contents").html(templete);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//フォロワーリスト
|
||||
function fer(user, more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (user == "--now") {
|
||||
var user = $('#his-data').attr("user-id");
|
||||
}
|
||||
if (more) {
|
||||
var sid = $("#his-follower-list .cvo").last().attr("user-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + user + "/followers" +
|
||||
plus;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json);
|
||||
if (more) {
|
||||
$("#his-follower-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-follower-list-contents").html(templete);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//以下自分のみ
|
||||
//お気に入り一覧
|
||||
function showFav(more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (more) {
|
||||
var sid = $("#his-fav-list .cvo").last().attr("toot-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/favourites" + plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = parse(json);
|
||||
if (more) {
|
||||
$("#his-fav-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-fav-list-contents").html(templete);
|
||||
}
|
||||
jQuery("time.timeago").timeago();
|
||||
});
|
||||
}
|
||||
|
||||
//ミュートリスト
|
||||
function showMut(more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (more) {
|
||||
var sid = $("#his-muting-list .cvo").last().attr("user-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/mutes" + plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json);
|
||||
if (more) {
|
||||
$("#his-muting-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-muting-list-contents").html(templete);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//ブロックリスト
|
||||
function showBlo(more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (more) {
|
||||
var sid = $("#his-blocking-list .cvo").last().attr("user-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/blocks" + plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json);
|
||||
if (more) {
|
||||
$("#his-blocking-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-blocking-list-contents").html(templete);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//フォロリクリスト
|
||||
function showReq(more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (more) {
|
||||
var sid = $("#his-request-list .cvo").last().attr("user-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/follow_requests" + plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = userparse(json, 'true');
|
||||
if (more) {
|
||||
$("#his-request-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-request-list-contents").html(templete);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//ドメインブロックリスト
|
||||
function showDom(more, acct_id) {
|
||||
if (!acct_id) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
}
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
if (more) {
|
||||
var sid = $("#his-domain-list .cvo").last().attr("user-id");
|
||||
var plus = "?max_id=" + sid;
|
||||
} else {
|
||||
var plus = "";
|
||||
}
|
||||
var start = "https://" + domain + "/api/v1/domain_blocks" + plus
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
//body: JSON.stringify({})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var templete = "";
|
||||
Object.keys(json).forEach(function(key) {
|
||||
var domain = json[key];
|
||||
templete = templete + domain +
|
||||
'<i class="material-icons gray pointer" onclick="domainblock(\'' +
|
||||
domain + '\',\'DELETE\')">cancel</i>' +
|
||||
'<div class="divider"></div>';
|
||||
});
|
||||
if (more) {
|
||||
$("#his-domain-list-contents").append(templete);
|
||||
} else {
|
||||
$("#his-domain-list-contents").html(templete);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//プロフ編集
|
||||
function profeditShow(json) {
|
||||
$("#his-name-val").val(json.display_name);
|
||||
var des = json.note;
|
||||
des = des.replace(/<br \/>/g, "\n");
|
||||
des = des.replace("<p>", "");
|
||||
des = des.replace("</p>", "");
|
||||
$("#his-des-val").val(des);
|
||||
}
|
72
js/userdata/prof-edit.js
Normal file
72
js/userdata/prof-edit.js
Normal file
@@ -0,0 +1,72 @@
|
||||
//プロフ編集
|
||||
//文字系
|
||||
function profedit() {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
todo("Updating...");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/update_credentials";
|
||||
var name = $("#his-name-val").val();
|
||||
var des = $("#his-des-val").val();
|
||||
fetch(start, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: JSON.stringify({
|
||||
display_name: name,
|
||||
note: des
|
||||
})
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
getdata();
|
||||
todc();
|
||||
});
|
||||
}
|
||||
|
||||
//画像系
|
||||
function imgChange(imgfile, target) {
|
||||
var acct_id = $('#his-data').attr("use-acct");
|
||||
todo("アップロードしています")
|
||||
if (!imgfile.files.length) {
|
||||
console.log("No Img");
|
||||
return;
|
||||
}
|
||||
var file = imgfile.files[0];
|
||||
var fr = new FileReader();
|
||||
fr.onload = function(evt) {
|
||||
var b64 = this.result;
|
||||
var blob = toBlob(b64, 'image/png');
|
||||
var fd = new FormData();
|
||||
fd.append(target, blob);
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/update_credentials";
|
||||
fetch(start, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
body: fd
|
||||
}).then(function(response) {
|
||||
console.log(response)
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
console.log(json);
|
||||
getdata();
|
||||
todc();
|
||||
});
|
||||
}
|
||||
$("#prof-change").html($("#prof-change").html());
|
||||
$("#header-change").html($("#header-change").html());
|
||||
fr.readAsDataURL(file);
|
||||
}
|
150
js/userdata/showOnTL.js
Normal file
150
js/userdata/showOnTL.js
Normal file
@@ -0,0 +1,150 @@
|
||||
//ユーザーデータ表示
|
||||
function udg(user, acct_id) {
|
||||
if (!user) {
|
||||
user = localStorage.getItem("user-id");
|
||||
}
|
||||
todo("User Data Loading...");
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/" + user;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
//moved設定時
|
||||
if (json.moved) {
|
||||
Materialize.toast(
|
||||
'このアカウントは移行します<button class="btn-flat toast-action" onclick="udg(\"' +
|
||||
json.moved + '\")">移行先を見る</button>', 4000)
|
||||
} else {
|
||||
$('#his-data').attr("user-id", user);
|
||||
$('#his-data').attr("use-acct", acct_id);
|
||||
$("#his-name").text(json.display_name);
|
||||
$("#his-acct").text(json.acct);
|
||||
$("#his-prof").attr("src", json.avatar);
|
||||
$('#his-data').css('background-image', 'url(' + json.header + ')');
|
||||
$("#his-sta").text(json.statuses_count);
|
||||
$("#his-follow").text(json.following_count);
|
||||
$("#his-follower").text(json.followers_count);
|
||||
$("#his-des").html(json.note);
|
||||
$('#his-data').modal('open');
|
||||
utl(json.id, '', acct_id);
|
||||
flw(json.id, '', acct_id);
|
||||
fer(json.id, '', acct_id);
|
||||
$('ul.tabs').tabs();
|
||||
$('#his-data').css('background-size', 'cover');
|
||||
$("#his-since").text(crat(json.created_at));
|
||||
}
|
||||
//自分の時
|
||||
if (json.acct == localStorage.getItem("user")) {
|
||||
$("#his-follow-btn").hide();
|
||||
$("#his-block-btn").hide();
|
||||
$("#his-mute-btn").hide();
|
||||
$("#his-notf-btn").hide();
|
||||
$("#his-domain-btn").hide();
|
||||
$("#my-data-nav").show();
|
||||
$("#his-data-nav").hide();
|
||||
$('ul.tabs').tabs('select_tab', 'his-tl');
|
||||
showFav('', acct_id);
|
||||
showBlo('', acct_id);
|
||||
showMut('', acct_id);
|
||||
showDom('', acct_id);
|
||||
showReq('', acct_id);
|
||||
profeditShow(json);
|
||||
} else {
|
||||
relations(user, acct_id);
|
||||
}
|
||||
todc();
|
||||
});
|
||||
}
|
||||
|
||||
//FF関係取得
|
||||
function relations(user, acct_id) {
|
||||
var domain = localStorage.getItem("domain_" + acct_id);
|
||||
var at = localStorage.getItem(domain + "_at");
|
||||
var start = "https://" + domain + "/api/v1/accounts/relationships?id=" + user;
|
||||
fetch(start, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'Authorization': 'Bearer ' + at
|
||||
},
|
||||
}).then(function(response) {
|
||||
return response.json();
|
||||
}).catch(function(error) {
|
||||
todo(error);
|
||||
console.error(error);
|
||||
}).then(function(json) {
|
||||
var json = json[0];
|
||||
console.log(json);
|
||||
if (json.following) {
|
||||
//自分がフォローしている
|
||||
$("#his-data").addClass("following");
|
||||
$("#his-follow-btn").text("フォロー解除");
|
||||
}
|
||||
if (json.followed_by) {
|
||||
//フォローされてる
|
||||
$("#his-relation").text("フォローされています");
|
||||
}
|
||||
if (json.blocking) {
|
||||
$("#his-data").addClass("blocking");
|
||||
$("#his-block-btn").text("ブロック解除");
|
||||
}
|
||||
if (json.muting) {
|
||||
$("#his-data").addClass("muting");
|
||||
$("#his-mute-btn").text("ミュート解除");
|
||||
}
|
||||
if (json.muting_notifications) {
|
||||
$("#his-data").addClass("mutingNotf");
|
||||
$("#his-notf-btn").text("通知ミュート解除");
|
||||
}
|
||||
if (json.domain_blocking) {
|
||||
$("#his-data").addClass("blockingDom");
|
||||
$("#his-domain-btn").text("ドメインブロック解除");
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//オールリセット
|
||||
function hisclose() {
|
||||
$('#his-data').modal('close');
|
||||
$("#his-name").text("Loading");
|
||||
$("#his-acct").text("");
|
||||
$("#his-prof").attr("src", "./img/loading.svg");
|
||||
$('#his-data').css('background-image', 'url(./img/loading.svg)');
|
||||
$("#his-sta").text("");
|
||||
$("#his-follow").text("");
|
||||
$("#his-follower").text("");
|
||||
$("#his-des").html("");
|
||||
$('#his-data').css('background-size', 'cover');
|
||||
$("#his-since").text("");
|
||||
$("#his-data").removeClass("following");
|
||||
$("#his-data").removeClass("muting");
|
||||
$("#his-data").removeClass("blocking");
|
||||
$("#his-data").removeClass("mutingNotf");
|
||||
$("#his-data").removeClass("blockingDom");
|
||||
$("#his-follow-btn").show();
|
||||
$("#his-block-btn").show();
|
||||
$("#his-mute-btn").show();
|
||||
$("#his-notf-btn").show();
|
||||
$("#his-domain-btn").show();
|
||||
$("#his-follow-btn").text("フォロー");
|
||||
$("#his-mute-btn").text("ミュート");
|
||||
$("#his-block-btn").text("ブロック");
|
||||
$("#his-notf-btn").text("通知ミュート");
|
||||
$("#his-domain-btn").text("ドメインブロック");
|
||||
$("#his-relation").text("");
|
||||
$("#my-data-nav").hide();
|
||||
$("#his-data-nav").show();
|
||||
$(".cont-series").html("");
|
||||
$("#domainblock").val("");
|
||||
}
|
Reference in New Issue
Block a user