TheDesk Airi (ver.5)

This commit is contained in:
cutls 2018-03-15 04:42:48 +09:00
parent 686d1cd922
commit 2715f602d5
21 changed files with 538 additions and 177 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
*.bat *.bat
*.zip *.zip
/TheDesk-*/

View File

@ -1,10 +1,11 @@
## For Astarte(kirishima.cloud), My Primary Instance ## For Astarte(kirishima.cloud), My Primary Instance
TheDesk :thedesk: Airi (ver.3) TheDesk :thedesk: Airi (ver.3)
・デフォルトの絵文字に関するバグ修正 ・Spotify NowPlaying機能を追加
・改行の描画に関するバグ修正 ・脆弱性の修正
・返信に関するバグ修正 ・絵文字の描画に関する修正
・通知を効率化 【重要】このアップデートは以下の理由で推奨されます。
・脆弱性の修正
https://thedesk.top https://thedesk.top
:github: https://github.com/cutls/TheDesk #Desk #DeskUpdate :github: https://github.com/cutls/TheDesk #Desk #DeskUpdate

View File

@ -53,7 +53,7 @@ Linuxでご使用の方はチェックを入れて下さい。<br>
マストドンバージョン:<span id="ins-ver"></span><br> マストドンバージョン:<span id="ins-ver"></span><br>
マストドンアップデート:<span id="ins-sys"></span><br> マストドンアップデート:<span id="ins-sys"></span><br>
<script type="text/javascript" src="./js/ui/theme.js"></script> <script type="text/javascript" src="./js/ui/theme.js"></script>
<script type="text/javascript" src="./js/platform/end.js"></script>
<script type="text/javascript" src="./js/login/manager.js"></script> <script type="text/javascript" src="./js/login/manager.js"></script>
<script type="text/javascript" src="./js/login/instance.js"></script> <script type="text/javascript" src="./js/login/instance.js"></script>
<script type="text/javascript" src="./js/tl/date.js"></script> <script type="text/javascript" src="./js/tl/date.js"></script>
<script type="text/javascript" src="./js/platform/end.js"></script>

View File

@ -1,5 +1,5 @@
/*共通CSS*/ /*共通CSS*/
html,body{overflow:hidden; user-select: none; cursor:default; font-size:13px;} html,body{overflow:hidden; user-select: none; cursor:default; font-size:13px;height: 100vh;}
.btn { .btn {
margin: 5px; margin: 5px;
text-transform: none; text-transform: none;

View File

@ -12,6 +12,7 @@
} }
#sidebar{ #sidebar{
width:75px; width:75px;
min-width:75px;
height:100vh; height:100vh;
background-color:#e0e0e0; background-color:#e0e0e0;
display:flex; display:flex;
@ -83,7 +84,9 @@ iframe {
font-size:1.2em; font-size:1.2em;
} }
.emoji-img{ .emoji-img{
width:1.2rem; width: 20px;
vertical-align: middle;
margin: -3px 0 0;
} }
.tl-box{ height:calc(100% - 40px); overflow-y:scroll; overflow-x:hidden } .tl-box{ height:calc(100% - 40px); overflow-y:scroll; overflow-x:hidden }
.additional { .additional {

View File

@ -26,7 +26,7 @@
<script type="text/javascript" src="./js/ui/jquery-ui.min.js"></script> <script type="text/javascript" src="./js/ui/jquery-ui.min.js"></script>
<script> <script>
//トゥートリンク追加 //トゥートリンク追加
var ver="Airi (ver.4[fixed])"; var ver="Airi (ver.5)";
//betaを入れるとバージョンチェックしない //betaを入れるとバージョンチェックしない
//var ver="beta"; //var ver="beta";
var acct_id=0; var acct_id=0;
@ -35,59 +35,59 @@ var tlid=0;
</script> </script>
<textarea id="copy" style="top:-100px; position:fixed;"></textarea> <textarea id="copy" style="top:-100px; position:fixed;"></textarea>
<div id="masara"> <div id="masara">
<!--最初にログインする-->ログインしたいインスタンスのアドレス <!--最初にログインする--><span data-trans="want_login">ログインしたいインスタンスのアドレス</span>
<br> <br>
<input type="text" id="url" style="width:70%" placeholder="mstdn.jp"> <input type="text" id="url" style="width:70%" placeholder="mstdn.jp">
<div id="ins-suggest"> <div id="ins-suggest">
</div> </div>
<button class="btn waves-effect" onclick="instance()">Login</button> <button class="btn waves-effect" onclick="instance()">Login</button>
<br>Linuxでご使用の方はチェックを入れて下さい。 <br><span data-trans="linux_ck">Linuxでご使用の方はチェックを入れて下さい。</span>
<br> <br>
<input type="checkbox" class="filled-in" id="linux" /> <input type="checkbox" class="filled-in" id="linux" />
<label for="linux">コードセットアップ</label> <label for="linux" data-trans="code_setup">コードセットアップ</label>
<br> <br>
<span style="font-family:Open Sans;">Supports</span> <span style="font-family:Open Sans;">Supports</span>
<div id="support"> <div id="support">
</div> </div>
<br>各インスタンスの独自機能もAPIの範囲内で実装させていただきます。お知らせください。 <br><span data-trans="invite_before">各インスタンスの独自機能もAPIの範囲内で実装させていただきます。お知らせください。</span>
<a href="https://kirishima.cloud/@Cutls" target="_blank">Cutls P(@Cutls@kirishima.cloud)</a>まで。 <a href="https://kirishima.cloud/@Cutls" target="_blank">Cutls P(@Cutls@kirishima.cloud)</a><span data-trans="made">まで。</span>
<br>ログイン後は設定画面から@Cutls@kirishima.cloudにコンタクトをとることができます。 <br><span data-trans="invite_after">ログイン後は設定画面から@Cutls@kirishima.cloudにコンタクトをとることができます。</span>
<br> <br>
<button class="btn waves-effect indigo" onclick="about()">このソフトについて</button> <button class="btn waves-effect indigo" onclick="about()" data-trans="about">このソフトについて</button>
<br> <br>
</div> </div>
<div id="auth"> <div id="auth">
<!--PINコードで認証-->指定されたコードを貼り付けてください。ログインウィンドウは閉じていただいて構いません。 <!--PINコードで認証--><span data-trans="enter_code">指定されたコードを貼り付けてください。ログインウィンドウは閉じていただいて構いません。</span>
<br> <br>
<input type="text" id="code" placeholder="コードを入力"> <input type="text" id="code" placeholder="コードを入力" data-trans-placeholder="code">
<button class="btn waves-effect" onclick="code()">認証</button> <button class="btn waves-effect" onclick="code()" data-trans="auth">認証</button>
<br> <br>
</div> </div>
<div id="tl"> <div id="tl">
<!--TL--> <!--TL-->
<!--ドラッグハンドラ--> <!--ドラッグハンドラ-->
<div id="drag"> <div id="drag">
<div id="drag-content">ここにドラッグして添付(ドラッグと同時にアップロードされます) <div id="drag-content" data-trans="drag_here">ここにドラッグして添付(ドラッグと同時にアップロードされます)
<br> <br>
<button class="btn waves-effect" onclick="closedrop()">閉じる</button> <button class="btn waves-effect" onclick="closedrop()" data-trans="close">閉じる</button>
</div> </div>
</div> </div>
<!--カラム追加--> <!--カラム追加-->
<div id="add-box" class="hide z-depth-4 notf-box"> <div id="add-box" class="hide z-depth-4 notf-box">
<div class="input-field">アカウント選択 <div class="input-field"><span data-trans="your_acct">アカウント選択</span>
<br> <br>
<select id="add-acct-sel" class="acct-sel" style="color:black"></select> <select id="add-acct-sel" class="acct-sel" style="color:black"></select>
<label></label> <label></label>
</div> </div>
<div class="input-field"> <div class="input-field">
<select id="type-sel" style="color:black"> <select id="type-sel" style="color:black">
<option value="local">ローカル</option> <option value="local" data-trans="local">ローカル</option>
<option value="home">ホーム</option> <option value="home" data-trans="home">ホーム</option>
<option value="pub">連合</option> <option value="pub" data-trans="public">連合</option>
<option value="mix">統合(ローカルとホーム)</option> <option value="mix" data-trans="integrated">統合(ローカルとホーム)</option>
<option value="notf">通知</option> <option value="notf" data-trans="notification">通知</option>
</select> </select>
<label>表示するタイムライン</label> <label data-trans="show_tl">表示するタイムライン</label>
</div> </div>
<button class="btn waves-effect blue " style="width:calc( 100% - 10px);" onclick="addColumn()"> <button class="btn waves-effect blue " style="width:calc( 100% - 10px);" onclick="addColumn()">
<i class="material-icons left">add</i>追加 <i class="material-icons left">add</i>追加
@ -204,9 +204,9 @@ var tlid=0;
</div> </div>
<div id="sidebar-btm"> <div id="sidebar-btm">
<!--最小化--> <!--最小化-->
<div id="menu-btn" onclick="show()"> <div id="menu-btn" class="big-menu" onclick="show()">
<a class="waves-effect"> <a class="waves-effect">
<i class="large material-icons">mode_edit</i> <i class="material-icons big-icon">mode_edit</i>
<br> <br>
<span class="side-label">投稿</span> <span class="side-label">投稿</span>
</a> </a>
@ -235,6 +235,7 @@ var tlid=0;
</div> </div>
<span id="radio-sta" class="radio"></span> <span id="radio-sta" class="radio"></span>
<div id="radio-view" class="hide radio mize"> <div id="radio-view" class="hide radio mize">
<a onclick="nowplaying()" class="pointer"><i class="fa fa-spotify"></i>NowPlaying</a>
<span class="cbadge pointer waves-effect" onclick="Rplay('https://listen.moe/stream','Listen.moe')" data-name="Listen.moe">Listen.moe</span> <span class="cbadge pointer waves-effect" onclick="Rplay('https://listen.moe/stream','Listen.moe')" data-name="Listen.moe">Listen.moe</span>
<span class="cbadge pointer waves-effect" onclick="Rplay('http://itori.animenfo.com:443/;','AnimeNfo Radio')" data-name="AnimeNfo Radio">AnimeNfo Radio</span> <span class="cbadge pointer waves-effect" onclick="Rplay('http://itori.animenfo.com:443/;','AnimeNfo Radio')" data-name="AnimeNfo Radio">AnimeNfo Radio</span>
<span class="cbadge pointer waves-effect" onclick="Rplay('http://hyades.shoutca.st:8043/stream','LoFi hip hop Radio')" data-name="LoFi hip hop Radio">LoFi hip hop Radio</span> <span class="cbadge pointer waves-effect" onclick="Rplay('http://hyades.shoutca.st:8043/stream','LoFi hip hop Radio')" data-name="LoFi hip hop Radio">LoFi hip hop Radio</span>
@ -676,7 +677,7 @@ var tlid=0;
<!--左下メッセージ--> <!--左下メッセージ-->
<div id="message"> <div id="message">
</div> </div>
<!--Radio--> <!--Radio Happy(Yui) Taku Inoue-->
<audio src="" id="radio"></audio> <audio src="" id="radio"></audio>
<script type="text/javascript" src="./js/common/about.js"></script> <script type="text/javascript" src="./js/common/about.js"></script>
<script type="text/javascript" src="./js/tl/parse.js"></script> <script type="text/javascript" src="./js/tl/parse.js"></script>
@ -699,6 +700,7 @@ var tlid=0;
<script type="text/javascript" src="./js/ui/pip.js"></script> <script type="text/javascript" src="./js/ui/pip.js"></script>
<script type="text/javascript" src="./js/ui/radio.js"></script> <script type="text/javascript" src="./js/ui/radio.js"></script>
<script type="text/javascript" src="./js/ui/sort.js"></script> <script type="text/javascript" src="./js/ui/sort.js"></script>
<script type="text/javascript" src="./js/ui/spotify.js"></script>
<script type="text/javascript" src="./js/post/post.js"></script> <script type="text/javascript" src="./js/post/post.js"></script>
<script type="text/javascript" src="./js/post/reply.js"></script> <script type="text/javascript" src="./js/post/reply.js"></script>
<script type="text/javascript" src="./js/post/secure.js"></script> <script type="text/javascript" src="./js/post/secure.js"></script>

View File

@ -48,7 +48,7 @@ function defEmoji(target){
var after = now.substr(selin, now.length); var after = now.substr(selin, now.length);
newt = before+ emoji.emoji + after; newt = before+ emoji.emoji + after;
}else{ }else{
newt = now+emoji.emoji; newt = emoji.emoji+now;
} }
console.log(emoji.emoji); console.log(emoji.emoji);
$("#textarea").val(newt); $("#textarea").val(newt);

View File

@ -32,7 +32,7 @@ function load() {
var list = key * 1 + 1; var list = key * 1 + 1;
templete = '<div class="acct" id="acct_' + key + '">' + list + templete = '<div class="acct" id="acct_' + key + '">' + list +
'.<img src="' + acct.prof + '" width="40" height="40"><div class="text">' + '.<img src="' + acct.prof + '" width="40" height="40"><div class="text">' +
acct.name + '&nbsp;<span class="gray">' + acct.user + '@' + acct.domain + acct.name + '&nbsp;<span class="gray">' + escapeHTML(acct.user) + '@' + acct.domain +
'</span></div><button class="btn waves-effect disTar" onclick="data(\'' + '</span></div><button class="btn waves-effect disTar" onclick="data(\'' +
acct.domain + acct.domain +
'\')">インスタンスデータ表示</button><button class="btn waves-effect" onclick="refresh(' + '\')">インスタンスデータ表示</button><button class="btn waves-effect" onclick="refresh(' +

View File

@ -4,9 +4,9 @@ function mixtl(acct_id, tlid) {
localStorage.removeItem("morelock") localStorage.removeItem("morelock")
localStorage.setItem("now", type); localStorage.setItem("now", type);
todo("Integrated TL Loading...(Local)"); todo("Integrated TL Loading...(Local)");
//まずLocal
var domain = localStorage.getItem("domain_" + acct_id); var domain = localStorage.getItem("domain_" + acct_id);
var at = localStorage.getItem(domain + "_at"); var at = localStorage.getItem(domain + "_at");
//まずLocal
var start = "https://" + domain + "/api/v1/timelines/public?local=true"; var start = "https://" + domain + "/api/v1/timelines/public?local=true";
fetch(start, { fetch(start, {
method: 'GET', method: 'GET',
@ -19,17 +19,7 @@ function mixtl(acct_id, tlid) {
}).catch(function(error) { }).catch(function(error) {
todo(error); todo(error);
console.error(error); console.error(error);
}).then(function(json) { }).then(function(jsonL) {
//パースして描画
var templete = parse(json, 'mix', acct_id, tlid);
$("#timeline_" + tlid).html(templete[0]);
jQuery("time.timeago").timeago();
$(window).scrollTop(0);
var locals = templete[1];
var times = templete[2];
todo("Integrated TL Loading...(Home)");
//Home
var start = "https://" + domain + "/api/v1/timelines/home"; var start = "https://" + domain + "/api/v1/timelines/home";
fetch(start, { fetch(start, {
method: 'GET', method: 'GET',
@ -42,56 +32,36 @@ function mixtl(acct_id, tlid) {
}).catch(function(error) { }).catch(function(error) {
todo(error); todo(error);
console.error(error); console.error(error);
}).then(function(obj) { }).then(function(jsonH) {
//ホームのオブジェクトをUnix時間で走査 var homearr=[];
if (!$("[toot-id=" + obj[0].id + "]").length) { var timeline = jsonL.concat(jsonH);
$("#timeline_" + tlid + " .cvo").first().before(parse([obj[0]], 'home', timeline.sort(function(a,b){
acct_id)); if(date(a.created_at,"unix")>date(b.created_at,"unix")) return -1;
//delete obj[0]; if(date(a.created_at,"unix")<date(b.created_at,"unix")) return 1;
return 0;
});
timeline.splice(20);
var templete="";
Object.keys(timeline).forEach(function(key) {
var pkey=key*1+1;
if(pkey<20){
if(date(timeline[key].created_at,"unix")!=date(timeline[pkey].created_at,"unix")){
templete = templete+parse([timeline[key]], '', acct_id, tlid);
} }
//Localが遅すぎてHomeの全てより過去の場合
var unixL=date(json[0].created_at,"unix");
var unixH=date(obj[obj.length-1].created_at,"unix");
//console.log(unixH+"vs"+unixL)
if(unixH < unixL){
Object.keys(obj).forEach(function(key) {
var skey = obj.length - key - 1;
var toot = obj[skey];
var id = toot.id;
if ($("#timeline_" + tlid + " [toot-id=" + toot.id + "]").length < 1) {
//console.log(toot.id);
var tarunix = date(toot.created_at, 'unix');
var beforekey2;
var key2;
//console.log(locals)
//ホームのオブジェクトに対してLocalのオブジェクトを時間走査
Object.keys(times).forEach(function(key2) {
if (times[key2] < tarunix) {
var local = json[key2].id;
//console.log($.strip_tags(toot.content));
html = parse(
[toot], 'home', acct_id, tlid);
$("#timeline_" + tlid + " [toot-id=" + local + "]").before(html);
//console.log("#timeline_" + tlid + " [toot-id=" + local + "]");
tarunix = 0;
} }
}); });
}
}); $("#timeline_" + tlid).html(templete);
}else{
html = parse(
obj, 'home', acct_id, tlid);
$("#timeline_" + tlid).html(html);
}
todc();
mixre(acct_id, tlid); mixre(acct_id, tlid);
additional(acct_id, tlid); additional(acct_id, tlid);
jQuery("time.timeago").timeago(); jQuery("time.timeago").timeago();
todc();
}); });
}); });
} }
//Streamingに接続 //Streamingに接続
function mixre(acct_id, tlid) { function mixre(acct_id, tlid) {
var domain = localStorage.getItem("domain_" + acct_id); var domain = localStorage.getItem("domain_" + acct_id);
@ -181,10 +151,9 @@ function mixmore(tlid) {
var domain = localStorage.getItem("domain_" + acct_id); var domain = localStorage.getItem("domain_" + acct_id);
var at = localStorage.getItem(domain + "_at"); var at = localStorage.getItem(domain + "_at");
var sid = $("#timeline_" + tlid + " .cvo").last().attr("toot-id"); var sid = $("#timeline_" + tlid + " .cvo").last().attr("toot-id");
var len = $("#timeline_" + tlid + " .cvo").length
var start = "https://" + domain +
"/api/v1/timelines/public?local=true&max_id=" + sid; var start = "https://" + domain + "/api/v1/timelines/public?local=true&max_id="+sid;
console.log(start);
fetch(start, { fetch(start, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -196,13 +165,8 @@ function mixmore(tlid) {
}).catch(function(error) { }).catch(function(error) {
todo(error); todo(error);
console.error(error); console.error(error);
}).then(function(json) { }).then(function(jsonL) {
var templete = parse(json, 'mix', acct_id, tlid); var start = "https://" + domain + "/api/v1/timelines/home?max_id="+sid;
$("#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, { fetch(start, {
method: 'GET', method: 'GET',
headers: { headers: {
@ -214,35 +178,33 @@ function mixmore(tlid) {
}).catch(function(error) { }).catch(function(error) {
todo(error); todo(error);
console.error(error); console.error(error);
}).then(function(obj) { }).then(function(jsonH) {
if ($("[toot-id=" + obj[0].id + "]").length < 1) { var homearr=[];
$("#timeline_" + tlid + " .cvo").eq(len).before(parse([obj[0]], 'home', var timeline = jsonL.concat(jsonH);
acct_id)+'<div class="divider"></div>'); timeline.sort(function(a,b){
//delete obj[0]; if(date(a.created_at,"unix")>date(b.created_at,"unix")) return -1;
if(date(a.created_at,"unix")<date(b.created_at,"unix")) return 1;
return 0;
});
timeline.splice(20);
var templete="";
Object.keys(timeline).forEach(function(key) {
var pkey=key*1+1;
if(pkey<20){
if(date(timeline[key].created_at,"unix")!=date(timeline[pkey].created_at,"unix")){
templete = templete+parse([timeline[key]], '', acct_id, tlid);
} }
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 <1) {
if (key2 > tarunix) {
var local = locals[key2];
$("#timeline_" + tlid + " [toot-id=" + local + "]").after(parse([toot], 'home',
acct_id, tlid));
tarunix = 2147483647;
} }
}
});
}); });
$("#timeline_" + tlid).append(templete);
mixre(acct_id, tlid);
additional(acct_id, tlid); additional(acct_id, tlid);
jQuery("time.timeago").timeago(); jQuery("time.timeago").timeago();
todc(); todc();
}); });
}); });
} }

View File

@ -80,6 +80,56 @@ function notf(acct_id, tlid, sys) {
console.error('WebSocket Error ' + error); console.error('WebSocket Error ' + error);
}; };
} }
//一定のスクロールで発火
function notfmore(tlid) {
var multi = localStorage.getItem("column");
var obj = JSON.parse(multi);
var acct_id = obj[tlid].domain;
if (!type) {
var type = obj[tlid].type;
}else{
var data;
}
var sid = $("#timeline_" + tlid + " .cvo").last().attr("toot-id");
console.log(sid);
if (localStorage.getItem("morelock") != sid) {
localStorage.setItem("morelock", sid);
localStorage.setItem("now", type);
todo("Notfication TL MoreLoading");
var domain = localStorage.getItem("domain_" + acct_id);
var at = localStorage.getItem(domain + "_at");
var start = "https://" + domain + "/api/v1/notifications"+
"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="";
Object.keys(json).forEach(function(key) {
var obj = json[key];
if(obj.type!="follow"){
templete = templete+parse([obj], '', acct_id, tlid, -1);
}else{
templete = templete+userparse([obj.account], '', acct_id, tlid, -1);
}
});
$("#timeline_" + tlid).append(templete);
additional(acct_id, tlid);
jQuery("time.timeago").timeago();
localStorage.removeItem("morelock")
todc();
});
}
}
//通知トグルボタン //通知トグルボタン
function notfToggle(acct, tlid) { function notfToggle(acct, tlid) {

249
app/js/tl/old-mix.js Normal file
View File

@ -0,0 +1,249 @@
//Integrated TL
function mixtl(acct_id, tlid) {
var type = "mix";
localStorage.removeItem("morelock")
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, tlid);
$("#timeline_" + tlid).html(templete[0]);
jQuery("time.timeago").timeago();
$(window).scrollTop(0);
var locals = templete[1];
var times = templete[2];
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時間で走査
if (!$("[toot-id=" + obj[0].id + "]").length) {
$("#timeline_" + tlid + " .cvo").first().before(parse([obj[0]], 'home',
acct_id));
//delete obj[0];
}
//Localが遅すぎてHomeの全てより過去の場合
var unixL=date(json[0].created_at,"unix");
var unixH=date(obj[obj.length-1].created_at,"unix");
//console.log(unixH+"vs"+unixL)
if(unixH < unixL){
Object.keys(obj).forEach(function(key) {
var skey = obj.length - key - 1;
var toot = obj[key];
console.log(toot);
var id = toot.id;
if ($("#timeline_" + tlid + " [toot-id=" + toot.id + "]").length < 1) {
//console.log(toot.id);
var tarunix = date(toot.created_at, 'unix');
var beforekey2;
var key2;
//console.log(locals)
//ホームのオブジェクトに対してLocalのオブジェクトを時間走査
Object.keys(times).forEach(function(key2) {
if (times[key2] < tarunix) {
var local = json[key2].id;
//console.log($.strip_tags(toot.content));
html = parse(
[toot], 'home', acct_id, tlid);
$("#timeline_" + tlid + " [toot-id=" + local + "]").before(html);
//console.log("#timeline_" + tlid + " [toot-id=" + local + "]");
tarunix = 0;
}
});
}
});
}else{
html = parse(
obj, 'home', acct_id, tlid);
$("#timeline_" + tlid).html(html);
}
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)");
$("#notice_icon_" + tlid).removeClass("red-text");
}
websocketLocal[wslid].onopen = function(mess) {
console.log("Connect Streaming API(Local)");
$("#notice_icon_" + tlid).removeClass("red-text");
}
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=" + JSON.parse(mess.data).payload + "]").hide();
$("[toot-id=" + JSON.parse(mess.data).payload + "]").remove();
} else if (type == "update") {
var templete = parse([obj], '', acct_id, tlid);
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=" + JSON.parse(mess.data).payload + "]").hide();
$("[toot-id=" + JSON.parse(mess.data).payload + "]").remove();
} else if (type == "update") {
var templete = parse([obj], '', acct_id, tlid);
if (obj.visibility != "public" || obj.account.acct != obj.account.username) {
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();
}
}
}
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 len = $("#timeline_" + tlid + " .cvo").length
var start = "https://" + domain +
"/api/v1/timelines/public?local=true&max_id=" + sid;
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, 'mix', acct_id, tlid);
$("#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 < 1) {
$("#timeline_" + tlid + " .cvo").eq(len).before(parse([obj[0]], 'home',
acct_id)+'<div class="divider"></div>');
//delete obj[0];
}
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 <1) {
if (key2 > tarunix) {
var local = locals[key2];
$("#timeline_" + tlid + " [toot-id=" + local + "]").after(parse([toot], 'home',
acct_id, tlid));
tarunix = 2147483647;
}
}
});
});
additional(acct_id, tlid);
jQuery("time.timeago").timeago();
todc();
});
});
}

View File

@ -130,12 +130,6 @@ function parse(obj, mix, acct_id, tlid, popup) {
} }
} }
var id = toot.id; var id = toot.id;
//Integratedである場合はUnix時間をキーに配列を生成しておく
if (mix == "mix") {
local[date(obj[key].created_at, 'unix')] = toot.id;
times.push(date(obj[key].created_at, 'unix'));
var divider = '<div class="divider"></div>';
}
if (mix == "home") { if (mix == "home") {
var home = "Home TLより" var home = "Home TLより"
var divider = '<div class="divider"></div>'; var divider = '<div class="divider"></div>';
@ -169,7 +163,7 @@ function parse(obj, mix, acct_id, tlid, popup) {
} }
if (toot.spoiler_text && cw) { if (toot.spoiler_text && cw) {
var content = toot.content; var content = toot.content;
var spoil = toot.spoiler_text; var spoil = escapeHTML(toot.spoiler_text);
var spoiler = "cw cw_hide_" + toot.id; var spoiler = "cw cw_hide_" + toot.id;
var api_spoil = "gray"; var api_spoil = "gray";
var spoiler_show = '<a href="#" onclick="cw_show(\'' + toot.id + var spoiler_show = '<a href="#" onclick="cw_show(\'' + toot.id +
@ -187,7 +181,7 @@ function parse(obj, mix, acct_id, tlid, popup) {
'\')" class="nex parsed">続き…</a><br>'; '\')" class="nex parsed">続き…</a><br>';
} else { } else {
var content = toot.content; var content = toot.content;
var spoil = toot.spoiler_text; var spoil = escapeHTML(toot.spoiler_text);
var spoiler = ""; var spoiler = "";
var spoiler_show = ""; var spoiler_show = "";
} }
@ -218,7 +212,7 @@ function parse(obj, mix, acct_id, tlid, popup) {
'" class="emoji-img">'; '" class="emoji-img">';
var regExp = new RegExp(":" + shortcode + ":", "g"); var regExp = new RegExp(":" + shortcode + ":", "g");
content = content.replace(regExp, emoji_url); content = content.replace(regExp, emoji_url);
spoil = toot.spoiler_text.replace(regExp, emoji_url); spoil = spoil.replace(regExp, emoji_url);
}); });
} }
var mediack = toot.media_attachments[0]; var mediack = toot.media_attachments[0];
@ -439,7 +433,7 @@ function userparse(obj, auth, acct_id, tlid, popup) {
} }
var memory = localStorage.getItem("notice-mem"); var memory = localStorage.getItem("notice-mem");
if (popup >= 0 && obj.length < 5 && noticetext != memory) { if (popup >= 0 && obj.length < 5 && noticetext != memory) {
Materialize.toast(toot.display_name+"にフォローされました", popup * 1000); Materialize.toast(escapeHTML(toot.display_name)+"にフォローされました", popup * 1000);
$(".notf-icon_" + tlid).addClass("red-text"); $(".notf-icon_" + tlid).addClass("red-text");
localStorage.setItem("notice-mem", noticetext); localStorage.setItem("notice-mem", noticetext);
noticetext = ""; noticetext = "";
@ -453,7 +447,7 @@ function userparse(obj, auth, acct_id, tlid, popup) {
'<img src="' + toot.avatar + '" width="40" class="prof-img" user="' + toot '<img src="' + toot.avatar + '" width="40" class="prof-img" user="' + toot
.acct + '"></a></div>' + .acct + '"></a></div>' +
'<div style="flex-grow:3; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;user-select:auto; cursor:text;"><big>' + '<div style="flex-grow:3; overflow: hidden;white-space: nowrap;text-overflow: ellipsis;user-select:auto; cursor:text;"><big>' +
toot.display_name + '</big></div>' + escapeHTML(toot.display_name) + '</big></div>' +
'<div class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;user-select:auto; cursor:text;"> @' + '<div class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;user-select:auto; cursor:text;"> @' +
toot.acct + locked + '</div>' + toot.acct + locked + '</div>' +
'</div>' + auth + '</div>' + auth +

View File

@ -182,6 +182,9 @@ function moreload(type, tlid) {
if (type == "mix") { if (type == "mix") {
mixmore(tlid); mixmore(tlid);
return; return;
}else if (type == "notf") {
notfmore(tlid);
return;
} }
localStorage.setItem("now", type); localStorage.setItem("now", type);
todo(cap(type) + " TL MoreLoading"); todo(cap(type) + " TL MoreLoading");
@ -205,6 +208,7 @@ function moreload(type, tlid) {
$("#timeline_" + tlid).append(templete); $("#timeline_" + tlid).append(templete);
additional(acct_id, tlid); additional(acct_id, tlid);
jQuery("time.timeago").timeago(); jQuery("time.timeago").timeago();
localStorage.removeItem("morelock")
todc(); todc();
}); });
} }

View File

@ -47,12 +47,14 @@ function xpand() {
if ($("#sidebar").hasClass("xed")) { if ($("#sidebar").hasClass("xed")) {
$(".side-label").show(); $(".side-label").show();
$("#sidebar").css('width', '75px'); $("#sidebar").css('width', '75px');
$("#sidebar").css('min-width', '75px');
$("#sidebar .big-menu i").addClass('big-icon'); $("#sidebar .big-menu i").addClass('big-icon');
$("#sidebar").removeClass("xed"); $("#sidebar").removeClass("xed");
$("#x-btn").text("keyboard_arrow_right"); $("#x-btn").text("keyboard_arrow_right");
localStorage.removeItem("xed"); localStorage.removeItem("xed");
} else { } else {
$("#sidebar").css('width', '24px'); $("#sidebar").css('width', '24px');
$("#sidebar").css('min-width', '24px');
$("#sidebar").addClass("xed"); $("#sidebar").addClass("xed");
$("#sidebar .big-menu i").removeClass('big-icon'); $("#sidebar .big-menu i").removeClass('big-icon');
$(".side-label").hide(); $(".side-label").hide();

View File

@ -25,7 +25,7 @@ function scrollck() {
} }
} }
//続きを読むトリガー //続きを読むトリガー
var scrt = $(this).find(".tl").height() - 1500; var scrt = $(this).find(".tl").height() - $(window).height();
var scr = $(this).scrollTop(); var scr = $(this).scrollTop();
if (scr > scrt) { if (scr > scrt) {
moreload('', tlid); moreload('', tlid);

View File

@ -211,6 +211,7 @@ load();
climute(); climute();
wordmute(); wordmute();
wordemp(); wordemp();
checkSpotify();
function climute(){ function climute(){
//クライアントミュート //クライアントミュート
var cli = localStorage.getItem("client_mute"); var cli = localStorage.getItem("client_mute");

76
app/js/ui/spotify.js Normal file
View File

@ -0,0 +1,76 @@
function spotifyConnect(){
var auth = "https://accounts.spotify.com/authorize?client_id=0f18e54abe0b4aedb4591e353d3aff69&redirect_uri=https://thedesk.top/spotify-connect&response_type=code&scope=user-read-currently-playing";
const {
shell
} = require('electron');
shell.openExternal(auth);
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('quit', 'go');
}
function spotifyDisconnect(){
localStorage.removeItem("spotify");
localStorage.removeItem("spotify-refresh");
checkSpotify();
}
function checkSpotify(){
if(localStorage.getItem("spotify")){
$("#spotify-enable").addClass("disabled");
$("#spotify-disable").removeClass("disabled");
}else{
$("#spotify-enable").removeClass("disabled");
$("#spotify-disable").addClass("disabled");
}
console.log(localStorage.getItem("spotify-refresh"));
}
function nowplaying(){
var start = "https://thedesk.top/now-playing?at="+localStorage.getItem("spotify")+"&rt="+localStorage.getItem("spotify-refresh");
var at = localStorage.getItem("spotify");
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);
var item=json.item;
var content=localStorage.getItem("np-temp");
if(!content){
var content="#NowPlaying {song} / {album} / {artist}\n{url} #Spotify-with-TheDesk";
}
var regExp = new RegExp("{song}", "g");
content = content.replace(regExp, item.name);
var regExp = new RegExp("{album}", "g");
content = content.replace(regExp, item.album.name);
var regExp = new RegExp("{artist}", "g");
content = content.replace(regExp, item.artists[0].name);
var regExp = new RegExp("{url}", "g");
content = content.replace(regExp, item.href);
$("#textarea").val(content);
});
}
function spotifySave(){
var temp=$("#np-temp").val();
localStorage.setItem("np-temp", temp);
Materialize.toast("NowPlaying文章を更新しました。", 3000);
}
if(location.search){
var m = location.search.match(/\?mode=([a-zA-Z-0-9]+)\&code=(.+)/);
var mode=m[1];
var codex=m[2];
if(mode=="spotify"){
var coder=codex.split(":");
localStorage.setItem("spotify", coder[0]);
localStorage.setItem("spotify-refresh", coder[1]);
}else{
}
}

View File

@ -123,6 +123,16 @@ ipc.on('download-btn', (e, args) => {
var zip="TheDesk-win32-ia32.zip"; var zip="TheDesk-win32-ia32.zip";
} }
}else if(platform=="linux"){ }else if(platform=="linux"){
const options = {
type: 'info',
title: 'Linux Supporting System',
message: "thedesk.topをブラウザで開きます。",
buttons: ['OK']
}
dialog.showMessageBox(options, function(index) {
shell.openExternal("https://thedesk.top");
})
return;
if(bit=="x64"){ if(bit=="x64"){
var zip="TheDesk-linux-x64.zip"; var zip="TheDesk-linux-x64.zip";
}else if(bit=="ia32"){ }else if(bit=="ia32"){
@ -226,17 +236,6 @@ ipc.on('about', (e, args) => {
"resizable": false }); "resizable": false });
window.loadURL('file://' + __dirname + '/about.html?ver='+ver); window.loadURL('file://' + __dirname + '/about.html?ver='+ver);
return "true" return "true"
/*
openAboutWindow({
icon_path: join(__dirname, 'desk.png'),
copyright: 'Copyright (c) TheDesk on Mastodon 2018 & Cutls.com 2015 All Rights Reserved. CDN provided by AWS CloudFront.',
license: 'This work is licensed under TheDesk LICENSE. See also GitHub.',
description: 'ここに表示されているバージョンは内部バージョンで、一般的に使われている愛称とは異なります。',
bug_report_url: 'https://cutls.com/report',
css_path: join(__dirname, './css/about.css'),
adjust_window_size: true
});
*/
}); });
ipc.on('column-del', (e, args) => { ipc.on('column-del', (e, args) => {

View File

@ -1,6 +1,6 @@
{ {
"name": "TheDesk", "name": "TheDesk",
"version": "13.4.1", "version": "13.5.0",
"description": "TheDesk on Mastodonはシンプルと多機能を両立したデスクトップ向けクライアントです", "description": "TheDesk on Mastodonはシンプルと多機能を両立したデスクトップ向けクライアントです",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

View File

@ -168,6 +168,22 @@
<span class="emphasized"> 強調色(テーマによって異なります。) </span> <span class="emphasized"> 強調色(テーマによって異なります。) </span>
</div> </div>
</li> </li>
<li>
<div class="collapsible-header">
<i class="fa fa-spotify"></i>SpotifyとNowPlayingの設定
</div>
<div class="collapsible-body">
<i class="material-icons nex" title="Radio(Select/Pause)">play_circle_outline</i>ボタンで表示されるメニューから簡単にNowPlayingができます。<br>
Windowsのみの対応です。APIの性質上thedesk.topへアクセスします。<br>
<a onclick="spotifyConnect()" class="btn waves-effect nex" style="width:100%; max-width:200px; background-color:#1ed760;" id="spotify-enable"><i class="fa fa-spotify left"></i>接続</a>
<a onclick="spotifyDisconnect()" class="btn waves-effect nex disabled" style="width:100%; max-width:200px; background-color:#1ed760;" id="spotify-disable"><i class="fa fa-spotify left"></i>切断</a>
<br>トゥートテンプレート<br>
<textarea id="np-temp" class="materialize-textarea" data-length="500">#NowPlaying {song} / {album} / {artist}
{url} #Spotify-with-TheDesk</textarea><br>
テンプレート:{song}:曲名/{album}:アルバム名/{artist}:アーティスト名/{url}:各曲のSpotifyのURL<br>
<button onclick="spotifySave()" class="btn waves-effect" style="width:100px;">設定</button>
</div>
</li>
</ul> </ul>
<br> <br>
<a href="index.html" class="btn waves-effect orange nex" style="width:100%; max-width:200px;"><i class="material-icons left">undo</i>戻る</a> <a href="index.html" class="btn waves-effect orange nex" style="width:100%; max-width:200px;"><i class="material-icons left">undo</i>戻る</a>
@ -223,6 +239,7 @@
<script type="text/javascript" src="./js/common/about.js"></script> <script type="text/javascript" src="./js/common/about.js"></script>
<script type="text/javascript" src="./js/platform/end.js"></script> <script type="text/javascript" src="./js/platform/end.js"></script>
<script type="text/javascript" src="./js/login/logout.js"></script> <script type="text/javascript" src="./js/login/logout.js"></script>
<script type="text/javascript" src="./js/ui/spotify.js"></script>
<script type="text/javascript" src="./js/ui/settings.js"></script> <script type="text/javascript" src="./js/ui/settings.js"></script>
<script type="text/javascript" src="./js/ui/theme.js"></script> <script type="text/javascript" src="./js/ui/theme.js"></script>
<script type="text/javascript" src="./js/tl/date.js"></script> <script type="text/javascript" src="./js/tl/date.js"></script>

View File

@ -1 +1 @@
{"warn":"これはGCPにアップして下さい","warn2":"これはGCPにアップして下さい","warn3":"これはGCPにアップして下さい","desk":"Airi (ver.4[fixed])","date":"2018-03-14","detail":"内部V:13.4.0|いくつかのバグを修正。機能改修。"} {"warn":"これはGCPにアップして下さい","warn2":"これはGCPにアップして下さい","warn3":"これはGCPにアップして下さい","desk":"Airi (ver.5)","date":"2018-03-15","detail":"内部V:13.5.0|バグ修正。Spotify Now Playing対応"}