TheDesk Mio (ver.3)

This commit is contained in:
cutls 2018-05-20 15:17:10 +09:00
parent a379617427
commit de8f063aea
29 changed files with 591 additions and 93 deletions

View File

@ -1,22 +1,28 @@
## For Astarte(kirishima.cloud), My Primary Instance
TheDesk :thedesk: Mio (ver.1)
・Adobeフォトエディタ
・トゥートボックスUI変更。よりコンパクトに
・サイドバーの挙動修正
・名前のカスタム絵文字に対応
・マウスオーバーでアクションを表示
・ブーストの言及元を簡単チェック
TheDesk :thedesk: Mio (ver.3)
・macOS版正式リリース
・Spotifyなうぷれ改修(アートワーク投稿)
・iTunesなうぷれ機能(macOS必須)
・メインアカウント機能(起動時や投稿後のアカウントを指定)
・エアリプソース確認が投稿者のアカウントのLTLに
・未認証TLのトゥートをメインアカウントで詳細表示できるように
・Nano機能がウィンドウ位置を記憶するように
・DMタイムラインを実装
・(imastodon.net)トレンドタグ表示機能
ほか
https://thedesk.top
:github: https://github.com/cutls/TheDesk #Desk #DeskUpdate
## For Other Instances
PCクライアントTheDesk Mio (ver.1)
・Adobeフォトエディタを内包。
・トゥートボックスUI変更。よりコンパクトに
・名前のカスタム絵文字に対応
・ブーストの言及元を簡単チェック
TheDeskはマルチカラムマルチアカウントはもちろんのことなにかとマストドンライフをシンプルに効率化するクライアントです。
PCクライアントTheDesk Mio (ver.3)
・Spotifyなうぷれ改修(アートワーク投稿)
・iTunesなうぷれ機能(macOS必須)
・メインアカウント機能(起動時や投稿後のアカウントを指定)
・エアリプソース確認が投稿者のアカウントのLTLに
・未認証TLのトゥートをメインアカウントで詳細表示できるように
・Nano機能がウィンドウ位置を記憶するように
・DMタイムラインを実装
・(imastodon.net)トレンドタグ表示機能
https://thedesk.top

View File

@ -1,31 +1,24 @@
# TheDesk LICENSE v3
# TheDesk LICENSE v4
(C)TheDesk 2018 all rights reserved. Website:[https://thedesk.top](https://thedesk.top)
以下のライセンスに基づき当ソフトウェアを公開します。
- 以下の条件の範囲内で個人ないし団体による再頒布を認めます。
- 必ず上記コピーライトと本ライセンス条項を改変無く含めること。(必ず年度が2018であること。他言語翻訳を付与する場合も原文を表記。)
- 変更を含め全てのコードを公開すること。商用利用やライセンスの変更は認めない。依存パッケージのライセンスにも従っているものとする。
- プラットフォームはElectronやCordova、またはそれに準ずるものであること。Webアプリケーションとしての配布は認めない。
- TheDeskとして他のプラットフォームに移植する場合、コードを一切変更してはならない。
- 改変する場合、必ずソフトウェアのタイトルの末尾が"Powered by TheDesk"であり、ユーザーの見えるところにTheDesk [使用バージョン名]を表示すること。
- 改変する場合、一切thedesk.topにアクセスしてはならない。TheDeskは標準でバージョン確認のためにthedesk.topにアクセスする。
- 改変する場合、サポートインスタンスを廃止すること。
- 改変する場合、アイコンを必ず変更するし、かつそれがTheDeskを想起させるものであること。
- このソフトウェアを改変して同時に複数インスタンスへ投稿させてはならない。
- 必ず上記コピーライトと本ライセンス条項を改変無く含めること。(必ず年度が2018であること。他言語翻訳を付与する場合も原文を表記。)
- このソフトウェアを改変して同時に複数インスタンスへ投稿させてはならない。
- このソフトウェアの使用、再頒布に伴う一切の責任をTheDeskは負いません。
- このソフトウェアを通じて投稿される内容やAPIを通じたアクションは全て投稿者が権利を主張でき、責務を負うことになります。
- APIを通じたアクションは、全てそのインスタンスの規約に従っていなければなりません。特記無き場合、法的責任はそのインスタンスのホストの所在国の法律に従って下さい。
- 利用しているインスタンスに関わらないTheDeskに起因する法的責任は日本国の法律に従います。
- [https://thedesk.top](https://thedesk.top)で公式に頒布されるソフトのみ[kirishima.cloud](https://kirishima.cloud)(アスタルテ)公認クライアントです。
このライセンス条項は2018年3月27日以降であり、TheDesk Airi (ver.9)以降をダウンロードした際に効力を持ちます。
- [https://thedesk.top](https://thedesk.top)で公式に頒布されるソフトのみオリジナルソフトウェアです。あなた自身がビルドしたものはオリジナルではありません。
このライセンス条項は2018年5月20日以降であり、TheDesk Mio (ver.3)以降をダウンロードした際に効力を持ちます。
以下バージョンとコードネームの比較です。
_斜字_ はTheDeskには採用していません。前作等に使用されています。
__太字__ は2018年3月27日現在のTheDeskで使用されたコードネームです。
__太字__ は2018年5月20日現在のTheDeskで使用されたコードネームです。
[カッコ囲み]は飛ばされることが確定しています。バージョンの番号も飛ばされます。
52以降が必要になったときに使用します。
1. _Rin_oct
1. _Rin_
1. _Anzu_
1. _Kanako_
1. _Kaede_

View File

@ -18,7 +18,7 @@ TheDeskを関西で開発しています。[Cutls Portal](https://the.cutls.com)
## License
[TheDesk LICENSE v3](https://github.com/cutls/TheDesk/blob/master/LICENSE.md)
[TheDesk LICENSE v4](https://github.com/cutls/TheDesk/blob/master/LICENSE.md)
## Component/構成
@ -37,9 +37,11 @@ Japanese
## Requirement/環境
- Windows (to launch TheDesk/実行に必要) / Linux (x64/ia32/armv7l)
- Electron beta.1.8.4
- Electron 1.8.4
- electron-dl
- Jimp(Node.js)
- itunes-nowplaying-mac(for macOS)
- node-notifier
- Ability to read unformated files!
## See also/詳しく

View File

@ -11,8 +11,10 @@
<link href='./css/userdata.css' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Open+Sans:300" rel="stylesheet">
<style>.acct{display:flex; justify-content:space-around;}
.text{overflow-x: scroll;}
.card{width:400px; background-color: #9e9e9e; margin:10px; }
body,html{overflow-y: scroll;}
#acct-list{display:flex; flex-wrap:wrap; color:white; align-items: flex-start}
.lts{font-size:150%}
</style>
<meta charset="utf-8">
</head>
@ -24,13 +26,14 @@ body,html{overflow-y: scroll;}
<script type="text/javascript" src="./js/common/time.js"></script>
<script type="text/javascript" src="./js/common/modal.js"></script>
<a href="index.html" class="btn waves-effect orange nex" style="width:100%; max-width:200px;">戻る</a><br>
<div id="acct-list" class="row"></div>
<h5>アカウント一覧</h5>
<div id="acct-list"></div>
<div class="divider"></div>
アカウントを追加<br>
<h5>アカウントを追加</h5><br>
<div id="add">
<div class="row">
<div class="col s6">
<input type="text" id="url" style="width:70%" placeholder="mstdn.jp">
<input type="text" id="url" style="width:70%" placeholder="ex)mstdn.jp">
<div id="ins-suggest"></div>
Windows以外でご使用の方やPleromaにログインされる方はチェックを入れて下さい。<br>
<input type="checkbox" class="filled-in" id="linux" />
@ -42,7 +45,12 @@ body,html{overflow-y: scroll;}
<div id="support" class="collection transparent"></div>
</div>
</div>
<h5>メインアカウント</h5>
<div class="input-field" style="width:300px"><span data-trans="your_acct">アカウント選択</span>
<br>
<select id="main-acct-sel" class="acct-sel" style="color:black" onchange="mainacct()"></select>
<label></label>
</div>
</div>
<div id="auth" style="display:none">
指定されたコードを貼り付けてください。ログインウィンドウは閉じていただいて構いません。<br>

View File

@ -26,7 +26,7 @@
<script type="text/javascript" src="./js/ui/jquery-ui.min.js"></script>
<script>
//必ずアプデ時のremove instance消して
var ver="Mio (ver.2)";
var ver="Mio (ver.3)";
//betaを入れるとバージョンチェックしない
//var ver="beta";
var acct_id=0;
@ -298,11 +298,11 @@ var tlid=0;
<span><span id="imgup"></span><span id="imgsel"><i class="waves-effect material-icons gray" onclick="fileselect()" title="ファイルを選択">photo_library</i></span></span>
<i class="waves-effect gray material-icons" onclick="adobe()" title="Adobeフォトエディタ">format_shapes</i>
<i class="waves-effect gray material-icons" onclick="emoji()" title="絵文字を挿入">tag_faces</i>
<a onclick="nowplaying('spotify')" class="pointer waves-effect gray" title="Spotify Now Playing(アカウント連携が必要です)Ctrl+Shift+N"><i class="fa fa-spotify" style="font-size:24px;"></i></a>
<a class="pointer waves-effect gray" id="npbtn" title="NowPlaying[クリックでSpotify(アカウント連携が必要です)/右クリックでiTunes(macOSが必要です)]"><i class="material-icons" style="font-size:24px;">music_note</i></a>
<i class="material-icons nex gray waves-effect" title="トゥートボックスのクリア(Ctrl+Shit+C)" data-trans-title="post_box_clear" id="clear">clear</i>
</div>
<div class="col s11 mize" style="margin-bottom:5px; padding:0;">
<div class="col s12 mize" style="margin-bottom:5px; padding:0;">
<div id="taglist"></div>
<span id="preview" class="mize"></span>
<span class=" sml mize"><span data-trans="reply">返信モード</span>:
<span id="rec">いいえ</span>/<span data-trans="file">添付</span>:
@ -344,9 +344,8 @@ var tlid=0;
<!--絵文字ピッカー-->
<div id="emoji" class="hide shared z-depth-4">
<span class="gray sml">インスタンスによって実装が異なります。
<i>
<a onclick="emojiGet('true')" class="pointer">絵文字更新</a>
</i>
<i class="material-icons waves-effect" onclick="emoji()" title="このボックスを閉じる" data-trans-title="post_box_close">cancel</i>
<br>
</span>
<input type="text" id="emoji-suggest" placeholder="カスタム絵文字検索">

View File

@ -72,6 +72,10 @@ var idata={
localStorage.setItem("instance", JSON.stringify(idata));
function ck() {
var main = localStorage.getItem("main");
if(!main){
localStorage.setItem("main",0)
}
var domain = localStorage.getItem("domain_0");
var at = localStorage.getItem(domain + "_at");
//コード受信
@ -375,7 +379,11 @@ function multi() {
var obj = JSON.parse(multi);
}
var templete;
var last = localStorage.getItem("last-use");
if(localStorage.getItem("mainuse")=="main"){
var last = localStorage.getItem("main");
}else{
var last = localStorage.getItem("last-use");
}
var sel;
console.log(obj.length)
if(obj.length<1){
@ -393,11 +401,6 @@ function multi() {
}else{
$("#textarea").attr("data-length", 500)
}
if(domain=="knzk.me" || domain=="mstdn.y-zu.org"){
$("#type-sel").append('<option value="dm" data-trans="dm" id="direct-add">ダイレクトメッセージ</option>');
}else{
$("#direct-add").remove();
}
var profimg=localStorage.getItem("prof_"+key);
var domain=localStorage.getItem("domain_"+key);
if(!profimg){
@ -410,6 +413,11 @@ function multi() {
}else{
$("#faicon-btn").hide();
}
if(domain=="imastodon.net"){
trendTag();
}else{
$("#trendtag").html("");
}
} else {
sel = "";
}

View File

@ -30,17 +30,19 @@ function load() {
Object.keys(obj).forEach(function(key) {
var acct = obj[key];
var list = key * 1 + 1;
templete = '<div id="acct_' + key + '"><div class="col s1">' + list +
'.</div><div class="col s2"><img src="' + acct.prof + '" width="40" height="40"></div><div class="text col s3">' +
acct.name + '&nbsp;<span class="gray">' + escapeHTML(acct.user) + '@' + acct.domain +
'</span></div><div class="col s2"><button class="btn waves-effect disTar" onclick="data(\'' +
templete = '<div id="acct_' + key + '" class="card"><div class="card-content white-text"><span class="lts">' + list +
'.</span><img src="' + acct.prof + '" width="40" height="40"><span class="card-title">' +
acct.name + '</span>' + escapeHTML(acct.user) + '@' + acct.domain +
'</div><div class="card-action"><a class="waves-effect disTar pointer white-text" onclick="data(\'' +
acct.domain +
'\')">インスタンス情報</button></div><div class="col s2"><button class="btn waves-effect" onclick="refresh(' +
'\')"><i class="material-icons">info</i>インスタンス情報</a><a class="waves-effect disTar pointer white-text" onclick="refresh(' +
key +
')">情報更新</button></div><div class="col s2"><button class="btn waves-effect red disTar" onclick="multiDel(' +
key + ')">削除</button><br></div></div>';
')"><i class="material-icons">refresh</i>情報更新</a><a class="waves-effect disTar pointer red-text" onclick="multiDel(' +
key +
')"><i class="material-icons">delete</i>削除</a></div></div>';
$("#acct-list").append(templete);
});
multisel();
var acctN = localStorage.getItem("acct");
if (!acctN) {
localStorage.setItem("acct", 0);
@ -336,3 +338,51 @@ function refresh(target) {
load();
});
}
//アカウントを選択…を実装
function multisel() {
var multi = localStorage.getItem("multi");
if (!multi) {
var obj = [];
var json = JSON.stringify(obj);
localStorage.setItem("multi", json);
} else {
var obj = JSON.parse(multi);
}
var templete;
var last = localStorage.getItem("main");
var sel;
console.log(obj.length)
if(obj.length<1){
$("#src-acct-sel").html('<option value="tootsearch">Tootsearch</option>');
$("#add-acct-sel").html('<option value="noauth">認証せずに見る</option>');
}else{
Object.keys(obj).forEach(function(key) {
var acct = obj[key];
var list = key * 1 + 1;
if (key == last) {
sel = "selected";
mainb="(既定)"
var domain = localStorage.getItem("domain_" + key);
var profimg=localStorage.getItem("prof_"+key);
var domain=localStorage.getItem("domain_"+key);
if(!profimg){
profimg="./img/missing.svg";
}
} else {
sel = "";
mainb=""
}
templete = '<option value="' + key + '" data-icon="' + acct.prof +
'" class="left circle" ' + sel + '>' + acct.user + '@' + acct.domain +mainb+
'</option>';
$(".acct-sel").append(templete);
});
}
$('select').material_select('update');
}
function mainacct(){
var acct_id = $("#main-acct-sel").val();
localStorage.setItem("main", acct_id);
Materialize.toast("メインアカウントを設定しました。", 3000);
}

View File

@ -28,6 +28,11 @@ function mdCheck(){
}else{
$("#faicon-btn").hide();
}
if(domain=="imastodon.net"){
trendTag();
}else{
$("#trendtag").html("");
}
if(idata[domain+"_letters"]){
$("#textarea").attr("data-length", idata[domain+"_letters"])
}else{

View File

@ -1,8 +1,12 @@
/*投稿系*/
//投稿
function post() {
if($("#toot-post-btn").prop("disabled")){
return
}
var str = $("#textarea").val();
var acct_id = $("#post-acct-sel").val();
$("#toot-post-btn").prop("disabled", true);
localStorage.setItem("last-use", acct_id);
todo("Posting");
var domain = localStorage.getItem("domain_" + acct_id);
@ -53,6 +57,7 @@ function post() {
$("body").addClass("mini-post");
$(".mini-btn").text("expand_less");
}
$("#toot-post-btn").prop("disabled", false);
todc();
clear();
}
@ -95,4 +100,7 @@ function clear() {
$("#post-acct-sel").prop("disabled", false);
$('select').material_select();
localStorage.removeItem("image");
if(localStorage.getItem("mainuse")=="main"){
multi();
}
}

View File

@ -37,7 +37,12 @@ function details(id, acct_id, tlid) {
replyTL(json.in_reply_to_id, acct_id);
}
context(id, acct_id);
beforeToot(id, acct_id);
if(json.account.acct!=json.account.username){
var dom=json.account.acct.replace(/.+@/g,'');
}else{
var dom=domain;
}
beforeToot(id, acct_id, dom);
userToot(id, acct_id, json.account.id);
faved(id, acct_id);
rted(id, acct_id);
@ -99,8 +104,8 @@ function context(id, acct_id) {
}
//前のトゥート(Back TL)
function beforeToot(id, acct_id) {
var domain = localStorage.getItem("domain_" + acct_id);
function beforeToot(id, acct_id, domain) {
//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;
@ -108,7 +113,6 @@ function beforeToot(id, acct_id) {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': 'Bearer ' + at
},
}).then(function(response) {
return response.json();
@ -116,7 +120,7 @@ function beforeToot(id, acct_id) {
todo(error);
console.error(error);
}).then(function(json) {
var templete = parse(json, '', acct_id);
var templete = parse(json, 'noauth', acct_id);
$("#toot-before").html(templete);
jQuery("time.timeago").timeago();
});
@ -262,6 +266,9 @@ function brws(){
}
//外部からトゥート開く
function detEx(url,acct_id){
if(acct_id=="main"){
acct_id=localStorage.getItem("main");
}
var domain = localStorage.getItem("domain_"+acct_id);
var at = localStorage.getItem(domain + "_at");
var start = "https://" + domain + "/api/v1/search?resolve=true&q="+url

View File

@ -105,8 +105,10 @@ function parse(obj, mix, acct_id, tlid, popup) {
//認証なしTL
if(mix=="noauth"){
var noauth="hide";
var antinoauth="";
}else{
var noauth="";
var antinoauth="hide";
}
//マウスオーバーのみ
var mouseover=localStorage.getItem("mouseover");
@ -512,32 +514,33 @@ function parse(obj, mix, acct_id, tlid, popup) {
'</span>' +
'' + mentions + tags + '</div>' +
'<div class="area-vis"></div>'+
'<div class="area-actions '+noauth+' '+mouseover+'" style="padding:0; margin:0; top:-20px; display:flex; justify-content:space-around; max-width:100%; ">' +
'<div class="action '+disp["re"]+'"><a onclick="re(\'' + toot.id +
'<div class="area-actions '+mouseover+'" style="padding:0; margin:0; top:-20px; display:flex; justify-content:space-around; max-width:100%; ">' +
'<div class="action '+antinoauth+'"><a onclick="detEx(\''+toot.url+'\',\'main\')" class="waves-effect waves-dark details" style="padding:0">詳細(メインアカウント経由)</a></div>' +
'<div class="action '+disp["re"]+' '+noauth+'"><a onclick="re(\'' + toot.id +
'\',\'' + toot.account.acct + '\',' +
acct_id + ',\''+visen+
'\')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートに返信"><i class="fa fa-share"></i></a></div>' +
'<div class="action '+can_rt+' '+disp["rt"]+'"><a onclick="rt(\'' + toot.id + '\',' + acct_id +
'<div class="action '+can_rt+' '+disp["rt"]+' '+noauth+'"><a onclick="rt(\'' + toot.id + '\',' + acct_id +
',\'' + tlid +
'\')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートをブースト"><i class="text-darken-3 fa fa-retweet ' +
if_rt + ' rt_' + toot.id + '"></i><span class="rt_ct">' + toot.reblogs_count +
'</span></a></div>' +
'<div class="action '+can_rt+' '+disp["qt"]+'"><a onclick="qt(\'' + toot.id + '\',' + acct_id +
'<div class="action '+can_rt+' '+disp["qt"]+' '+noauth+'"><a onclick="qt(\'' + toot.id + '\',' + acct_id +
',\'' + toot.account.acct +'\',\''+toot.url+
'\')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートを引用"><i class="text-darken-3 fa fa-quote-right"></i></a></div>' +
'<div class="action '+disp["fav"]+'"><a onclick="fav(\'' + toot.id + '\',' + acct_id +
'<div class="action '+disp["fav"]+' '+noauth+'"><a onclick="fav(\'' + toot.id + '\',' + acct_id +
',\'' + tlid +
'\')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートをお気に入り登録"><i class="fa text-darken-3 fa-star' +
if_fav + ' fav_' + toot.id + '"></i><span class="fav_ct">' + toot.favourites_count +
'</a></span></div>' +
'<div class="' + if_mine + ' action '+disp["del"]+'"><a onclick="del(\'' + toot.id + '\',' +
'<div class="' + if_mine + ' action '+disp["del"]+' '+noauth+'"><a onclick="del(\'' + toot.id + '\',' +
acct_id +
')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートを削除"><i class="fa fa-trash-o"></i></a></div>' +
'<div class="' + if_mine + ' action pin '+disp["pin"]+'"><a onclick="pin(\'' + toot.id + '\',' +
'<div class="' + if_mine + ' action pin '+disp["pin"]+' '+noauth+'"><a onclick="pin(\'' + toot.id + '\',' +
acct_id +
')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートをピン留め"><i class="fa fa-map-pin pin_' + toot.id + ' '+if_pin+'"></i></a></div>' +trans+
'<div class="action ' + if_mine + '"><a onclick="toggleAction(\'' + toot.id + '\',\''+tlid+'\',\''+acct_id+'\')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="text-darken-3 material-icons act-icon">expand_more</i></a></div>' +
'<div class="action"><a onclick="details(\'' + toot.id + '\',' + acct_id +
'<div class="action ' + if_mine + ' '+noauth+'"><a onclick="toggleAction(\'' + toot.id + '\',\''+tlid+'\',\''+acct_id+'\')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="text-darken-3 material-icons act-icon">expand_more</i></a></div>' +
'<div class="action '+noauth+'"><a onclick="details(\'' + toot.id + '\',' + acct_id +
',\''+tlid+'\')" class="waves-effect waves-dark btn-flat details" style="padding:0"><i class="text-darken-3 material-icons">more_vert</i></a></div>' +
'<span class="cbadge waves-effect '+viashow+' '+mine_via+'" onclick="client(\''+$.strip_tags(via)+'\')" title="via ' + $.strip_tags(via) + '">via ' +
via +

View File

@ -4,7 +4,8 @@ if(location.search){
var mode=m[1];
var codex=m[2];
if(mode=="tag"){
tl('tag',decodeURI(codex),0,'add');
var acct_id=localStorage.getItem("main");
tl('tag',decodeURI(codex),acct_id,'add');
}
}
//よく使うタグ
@ -45,6 +46,7 @@ function tagRemove(key) {
favTag();
}
function favTag(){
$("#taglist").html("");
var tagarr = localStorage.getItem("tag");
if(!tagarr){
var obj=[];
@ -58,10 +60,48 @@ function favTag(){
'<a onclick="tagRemove(\'' + key + '\')" class="pointer" title="#' + tag + 'をよく使うタグから削除">Unpin</a></span> ';
});
if(obj.length>0){
$("#suggest").append("My Tags:" + tags);
$("#taglist").append("My Tags:" + tags);
}else{
$("#suggest").append("");
$("#taglist").append("");
}
}
function trendTag(){
$("#trendtag").html("");
var domain="imastodon.net"
var at = localStorage.getItem(domain + "_at");
var start = "https://" + domain + "/api/v1/trend_tags"
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) {
var tags="";
json=json.score;
Object.keys(json).forEach(function(tag) {
tags = tags + '<a onclick="tagShow(\'' + tag + '\')" class="pointer">#' + tag + '</a><span class="hide" data-tag="' + tag + '"> <a onclick="tagTL(\'tag\',\'' + tag + '\',false,\'add\')" class="pointer" title="#' + tag + 'のタイムライン">TL</a> <a onclick="brInsert(\'#' + tag + '\')" class="pointer" title="#' + tag + 'でトゥート">Toot</a></span> ';
});
$("#taglist").append('<span id="trendtag">トレンドタグ<i class="material-icons pointer" onclick="trendTag()" style="font-size:12px">refresh</i>:' + tags+'</span>');
trendintervalset()
}else{
$("#taglist").html("");
}
});
}
function trendintervalset(){
setTimeout(trendTag, 6000000);
}
function tagTL(a,b,c,d){
var acct_id = $("#post-acct-sel").val();

View File

@ -141,6 +141,12 @@ function settings() {
}
localStorage.setItem("mouseover", movd);
var maind = $("[name=main]:checked").val();
var maint = $("[for=mn_"+maind+"]").text();
if (maind != localStorage.getItem("mainuse")) {
Materialize.toast("起動時・投稿時のアカウントを" + maint + "に設定しました。", 3000);
}
localStorage.setItem("mainuse", maind);
}
//読み込み時の設定ロード
@ -274,6 +280,12 @@ function load() {
var movt = "no";
}
$("#mov_" + movt).prop("checked", true);
var maint = localStorage.getItem("mainuse");
if (!maint) {
var maint = "remain";
}
$("#mn_" + maint).prop("checked", true);
}
//最初に読む
load();

View File

@ -25,7 +25,7 @@ function sortload(){
}
}
var html='<li class="drag-content" data-id="'+key+'" data-flag="'+flag+'"'+insert+'><a onclick="goColumn(' + key +
')" class="setting nex"><i class="material-icons waves-effect nex" title="このカラムへ">forward</i></a>'+localStorage.getItem("user_" + acct.domain)+"@"+localStorage.getItem("domain_" + acct.domain)+" "+cap(acct.type, acct.data)+' TL <a onclick="removeColumn(' + key +
')" class="setting nex"><i class="material-icons waves-effect nex" title="このカラムへ">forward</i></a>'+localStorage.getItem("user_" + acct.domain)+"@"+localStorage.getItem("domain_" + acct.domain)+" "+cap(acct.type, acct.data)+' <a onclick="removeColumn(' + key +
')" class="setting nex"><i class="material-icons waves-effect nex" title="このカラムを削除">cancel</i></a></li>';
$("#sort").append(html);
});
@ -33,7 +33,7 @@ function sortload(){
}
//TLのタイトル
function cap(type, data) {
function Scap(type, data) {
if (type == "home") {
return "Home"
} else if (type == "local") {

View File

@ -65,6 +65,10 @@ function nowplaying(mode){
}).then(function(json) {
console.log(json);
var item=json.item;
var img=item.album.images[0].url;
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('bmp-image', [img,0]);
var content=localStorage.getItem("np-temp");
if(!content || content==""){
var content="#NowPlaying {song} / {album} / {artist}\n{url}";
@ -86,20 +90,16 @@ function nowplaying(mode){
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('itunes', "");
ipc.on('itunesRes', function (event, arg) {
ipc.on('itunes-np', function (event, arg) {
var content=localStorage.getItem("np-temp");
if(!content || content==""){
var content="#NowPlaying {song} / {album} / {artist}\n{url}";
}
var str_array=arg.artist.split('');//1文字ずつ配列に入れる
var utf8Array=Encoding.convert(str_array, 'SJIS', 'AUTO');//UTF-8に変換
console.log(utf8Array);
var convert=Encoding.codeToString( utf8Array );
console.log(convert);
var regExp = new RegExp("{song}", "g");
content = content.replace(regExp, arg.name);
var regExp = new RegExp("{album}", "g");
content = content.replace(regExp, arg.album);
content = content.replace(regExp, arg.album.name);
var regExp = new RegExp("{artist}", "g");
content = content.replace(regExp, arg.artist);
var regExp = new RegExp("{url}", "g");
@ -126,4 +126,11 @@ if(location.search){
}
}
}
$("#npbtn").click(function() {
nowplaying('spotify');
});
$("#npbtn").bind('contextmenu', function() {
nowplaying('itunes');
return false;
});

View File

@ -6,7 +6,7 @@ if(location.search){
var mode=m[1];
var codex=m[2];
if(mode=="user"){
udgEx(codex,0);
udgEx(codex,'main');
}
}
function udgEx(user,acct_id){
@ -16,6 +16,9 @@ function udgEx(user,acct_id){
if(acct_id=="selector"){
acct_id = $("#user-acct-sel").val();
}
if(acct_id=="main"){
acct_id = localStorage.getItem("main");
}
console.log(user);
var domain = localStorage.getItem("domain_" + acct_id);
var at = localStorage.getItem(domain + "_at");

View File

@ -40,6 +40,7 @@ try {
height: 750
}; // デフォルトバリュー
}
// 全てのウィンドウが閉じたら終了
app.on('window-all-closed', function() {
if (process.platform != 'darwin') {
@ -121,16 +122,21 @@ ipc.on('native-notf', function(e, args) {
var bit=process.arch;
if(platform=="win32"){
Jimp.read(args[2], function (err, lenna) {
if (err) throw err;
lenna.write(tmp_img);
if(!err && lenna){
lenna.write(tmp_img);
var tmp_imge=tmp_img;
}else{
var tmp_imge="";
}
notifier.notify({
message: args[1],
title: args[0],
sound: false,//"Bottle",
icon : tmp_img,
icon : tmp_imge,
wait:false
}, function(error, response) {
});
});
}
});
@ -339,7 +345,21 @@ function about(){
window.loadURL('file://' + __dirname + '/about.html?ver='+ver);
return "true"
}
//
ipc.on('itunes', (e, args) => {
var platform=process.platform;
var bit=process.arch;
if(platform=="darwin"){
const nowplaying = require("itunes-nowplaying-mac")
nowplaying().then(function (value) {
console.log(value);
mainWindow.webContents.send('itunes-np', value);
}).catch(function (error) {
// 非同期処理失敗。呼ばれない
console.log(error);
});
}
});
ipc.on('file-select', (e, args) => {
dialog.showOpenDialog(null, {
properties: ['openFile', 'multiSelections'],
@ -385,14 +405,25 @@ ipc.on('bmp-image', (e, args) => {
});
ipc.on('nano', function (e, x, y) {
var window = new BrowserWindow({width: 300, height: 200,
var nano_info_path = join(app.getPath("userData"), "nano-window-position.json");
var window_pos;
try {
window_pos = JSON.parse(fs.readFileSync(nano_info_path, 'utf8'));
} catch (e) {
window_pos = [0,0]; // デフォルトバリュー
}
var nanowindow = new BrowserWindow({width: 300, height: 200,
"transparent": false, // ウィンドウの背景を透過
"frame": false, // 枠の無いウィンドウ
"resizable": false });
window.loadURL('file://' + __dirname + '/nano.html');
window.setAlwaysOnTop(true);
window.setPosition(0, 0);
return "true"
nanowindow.loadURL('file://' + __dirname + '/nano.html');
nanowindow.setAlwaysOnTop(true);
nanowindow.setPosition(window_pos[0], window_pos[1]);
nanowindow.on('close', function() {
fs.writeFileSync(nano_info_path, JSON.stringify(nanowindow.getPosition()));
});
return true;
})
ipc.on('adobe', (e, arg) => {
if(!arg){

59
app/node_modules/itunes-nowplaying-mac/README.md generated vendored Normal file
View File

@ -0,0 +1,59 @@
# itunes-nowplaying-mac
tested in macOS High Sierra 10.13.2 and iTunes 12.7.2.58
## install
```
npm install itunes-nowplaying-mac
```
## how to use
TypeScript:
```typescript
import nowplaying from "itunes-nowplyaing-mac"
nowplaying().then(console.log)
import {getRawData as nowplaying} from "itunes-nowplaying-mac"
nowplaying().then(console.log) // return iTunes raw data
```
JavaScript:
```javascript
const nowplaying = require("itunes-nowplaying-mac")
nowplaying().then(console.log)
nowplaying.getRawData().then(console.log) // return iTunes raw data
```
example return data:
```json
{
"name": "AnemoneStar",
"duration": 211.29299926757812,
"artist": "渋谷凛 (福原綾香)",
"composer": "Yasushi",
"album": {
"name": "THE IDOLM@STER CINDERELLA GIRLS STARLIGHT MASTER 01",
"artist": "",
"loved": false,
"disliked": false
},
"genre": "Soundtrack",
"track": {
"length": 7,
"number": 3
},
"disc": {
"length": 1,
"number": 1
},
"sampleRate": 44100,
"comment": "",
"loved": true,
"disliked": false,
"state": "playing"
}
```

View File

4
app/node_modules/itunes-nowplaying-mac/dist/demo.js generated vendored Normal file
View File

@ -0,0 +1,4 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("./index");
index_1.default().then(console.log);

30
app/node_modules/itunes-nowplaying-mac/dist/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,30 @@
export declare function getRawData(): Promise<{
[key: string]: any;
} | null>;
declare function getData(): Promise<{
name: string;
duration: number;
artist: string;
composer: string;
album: {
name: string;
artist: string;
loved: boolean;
disliked: boolean;
};
genre: string;
track: {
length: number;
number: number;
};
disc: {
length: number;
number: number;
};
sampleRate: number;
comment: string;
loved: boolean;
disliked: boolean;
state: "playing" | "paused";
} | null>;
export default getData;

70
app/node_modules/itunes-nowplaying-mac/dist/index.js generated vendored Normal file
View File

@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const child_process = require("child_process");
const path = require("path");
async function getRawData() {
const raw_res = await new Promise((resolve, reject) => {
var stdout = "";
var stderr = "";
var process = child_process.spawn("osascript", [path.join(__dirname, "itunes.js")]);
process.stdout.on("data", (data) => {
if (data instanceof Buffer) {
data = data.toString("utf-8");
}
stdout += data;
});
process.stderr.on("data", (data) => {
if (data instanceof Buffer) {
data = data.toString("utf-8");
}
stderr += data;
});
process.on("close", (code) => {
if (code != 0) {
reject(stderr);
}
else {
resolve(stdout);
}
});
});
const res = JSON.parse(raw_res);
return res;
}
exports.getRawData = getRawData;
async function getData() {
const res = await getRawData();
if (res == null) {
return null;
}
return {
name: res.name,
duration: res.duration,
artist: res.artist,
composer: res.composer,
album: {
name: res.album,
artist: res.albumArtist,
loved: res.albumLoved,
disliked: res.albumDisliked,
},
genre: res.genre,
track: {
length: res.trackCount,
number: res.trackNumber,
},
disc: {
length: res.discCount,
number: res.discNumber,
},
sampleRate: res.sampleRate,
comment: res.comment,
loved: res.loved,
disliked: res.disliked,
state: res.state,
};
}
Object.defineProperty(getData, "default", { value: getData });
module.exports = getData;
module.exports.getRawData = getRawData;
exports.default = getData;

17
app/node_modules/itunes-nowplaying-mac/dist/itunes.js generated vendored Normal file
View File

@ -0,0 +1,17 @@
"use strict";
var itunes = Application("iTunes");
var track = itunes.currentTrack;
function run(argv) {
var state = itunes.playerState()
if (state != "playing" && state != "paused") {
return "null"
}
track = track.properties();
Object.keys(track).filter(function (name) {
if (name.startsWith("purchase") || name.endsWith("ID")) {
track[name] = undefined;
}
});
track.state = state
return JSON.stringify(track, null, 4);
}

60
app/node_modules/itunes-nowplaying-mac/package.json generated vendored Normal file
View File

@ -0,0 +1,60 @@
{
"_from": "itunes-nowplaying-mac",
"_id": "itunes-nowplaying-mac@0.2.3",
"_inBundle": false,
"_integrity": "sha512-1n418TnV4BnpSP6IzuxVECgPYnlm/nUZIXsblvzFVu4+rxmswXPnz3xi8XUq0r28I9njTi3g6vmBFa5YFHb8TA==",
"_location": "/itunes-nowplaying-mac",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "itunes-nowplaying-mac",
"name": "itunes-nowplaying-mac",
"escapedName": "itunes-nowplaying-mac",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/itunes-nowplaying-mac/-/itunes-nowplaying-mac-0.2.3.tgz",
"_shasum": "88e39b78100f6b9cd864b8293f5391de8fcfbf72",
"_spec": "itunes-nowplaying-mac",
"_where": "/Users/aa/TheDesk/app",
"author": {
"name": "rinsuki"
},
"bugs": {
"url": "https://github.com/rinsuki/itunes-nowplaying-mac/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "tested in macOS High Sierra 10.13.2 and iTunes 12.7.2.58",
"devDependencies": {
"@types/node": "^9.3.0",
"typescript": "^2.6.2"
},
"engines": {
"node": ">= 7.6.0"
},
"homepage": "https://github.com/rinsuki/itunes-nowplaying-mac#readme",
"license": "MIT",
"main": "dist/index.js",
"name": "itunes-nowplaying-mac",
"os": [
"darwin"
],
"repository": {
"type": "git",
"url": "git+https://github.com/rinsuki/itunes-nowplaying-mac.git"
},
"scripts": {
"build": "tsc",
"prepublish": "npm run build",
"test": "echo \"Error: no test specified\" && exit 1"
},
"typings": "dist/index.d.ts",
"version": "0.2.3"
}

59
app/node_modules/itunes-nowplaying-mac/tsconfig.json generated vendored Normal file
View File

@ -0,0 +1,59 @@
{
"compilerOptions": {
/* Basic Options */
"target": "es2017", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation: */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
"declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./dist/", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
},
"include": [
"src/**/*.ts",
"src/**/*.js",
]
}

View File

@ -151,10 +151,18 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.<br>
<h5>itunes-nowplaying-mac</h5>
MIT LICENSE
<h5>Adobe Creative SDK</h5>
Please visit:
<a href="http://wwwimages.adobe.com/www.adobe.com/content/dam/acom/jp/legal/servicetou/Creative_SDK_API_and_Developer_Additional_TOU-ja_JP-20140602_1513.pdf" target="_blank">
This file
<i class="material-icons">
picture_as_pdf
</i></a>
<h5>Google Fonts</h5>
<ul>
<li>Open Sans:<a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0"> Apache License, Version 2.0 </a></li>
<li>Baloo Bhai:<a target="_blank" href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=OFL_web"> Open Font License </a></li>
<li>Material Icons:<a target="_blank" href="http://www.apache.org/licenses/LICENSE-2.0"> Apache License, Version 2.0 </a></li>
<li>IBM Plex Mono:<a target="_blank" href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;id=OFL_web"> Open Font License </a></li>
</ul>

View File

@ -1,6 +1,6 @@
{
"name": "TheDesk",
"version": "15.2.0",
"version": "15.3.0",
"description": "TheDesk on Mastodonはシンプルと多機能を両立したデスクトップ向けクライアントです",
"main": "main.js",
"scripts": {
@ -12,6 +12,7 @@
"dependencies": {
"electron-dl": "^1.11.0",
"jimp": "^0.2.28",
"itunes-nowplaying-mac": "^0.2.3",
"node-notifier": "5.2.1"
}
}

View File

@ -178,6 +178,14 @@
<label for="q_full">本文・URL・アカウント名
</label>
<br>
<h5>投稿後や起動時のアカウント</h5>
メインアカウントはアカウント設定で指定できます。投稿以外のアカウント選択にも影響します。<br>
<input class="with-gap" onchange="settings()" name="main" type="radio" id="mn_remain" value="remain" />
<label for="mn_remain">最後に使用したアカウント</label>
<input class="with-gap" onchange="settings()" name="main" type="radio" id="mn_main" value="main" />
<label for="mn_main">メインアカウント</label>
</label>
<br>
</div>
</li>
<li>

View File

@ -1 +1 @@
{"warn":"これはGCPにアップして下さい","warn2":"これはGCPにアップして下さい","warn3":"これはGCPにアップして下さい","desk":"Mio (ver.2)","date":"2018-05-12","detail":"内部V:15.2.0|バグ修正他"}
{"warn":"これはGCPにアップして下さい","warn2":"これはGCPにアップして下さい","warn3":"これはGCPにアップして下さい","desk":"Mio (ver.3)","date":"2018-05-20","detail":"内部V:15.3.0|機能追加たくさんあります。"}