TheDesk Airi (ver.1)

This commit is contained in:
cutls 2018-03-10 23:22:59 +09:00
parent 19eb4c2588
commit eacbdd2df0
32 changed files with 1004 additions and 107 deletions

View File

@ -1,13 +1,12 @@
## For Markdown-supporting Instances
## For Astarte(kirishima.cloud), My Primary Instance
[TheDesk](https://thedesk.top) :thedesk: Riina (ver.8)
・バグ修正
・プラットフォーム追加(サポート外となります)
[TheDesk](https://thedesk.top) :thedesk: Airi (ver.1)
・史上最大の機能追加数です。ここに書ききれないので[HP](https://thedesk.top)へ。
:github: [cutls/TheDesk](https://github.com/cutls/TheDesk) #Desk #DeskUpdate
## For Vanilla Instances
WindowsクライアントTheDesk Riina (ver.8)リリース
バグ修正
・プラットフォーム追加(サポート外となります)
Windows/LinuxクライアントTheDesk Airi (ver.1)リリース
史上最大の機能追加数です。
TheDeskはマルチカラムマルチアカウントはもちろんのことなにかとマストドンライフをシンプルに効率化するクライアントです。
https://thedesk.top

View File

@ -1,6 +1,6 @@
# TheDesk
Mastodon client for Windows
オープンソースSNSマストドンのWindowsクライアント
Mastodon client for Windows/Linux(Linux ver. is not supported by developer.)
オープンソースSNSマストドンのWindows/Linuxクライアント
Download:[TheDesk](https://thedesk.top)
Latest Info(Markdown Toot)/最新情報(マークダウン形式のトゥート): [LATEST.md](https://github.com/cutls/TheDesk/blob/master/LATEST.md)
@ -33,10 +33,11 @@ Japanese
## Requirement/環境
- Windows 64bit(to launch TheDesk/実行に必要)
- Windows (to launch TheDesk/実行に必要) / Linux (x64/ia32/armv7l)
- Electron beta.1.8.2-beta4
- electron-dl
- electron-about-window
- Jimp(Node.js)
- Ability to read unformated files!
### Why do we use Electron beta version?/Beta版の利用について

View File

@ -30,8 +30,9 @@
<input type="text" id="url" style="width:70%" placeholder="mstdn.jp">
<div id="ins-suggest"></div>
<button class="btn waves-effect" onclick="instance()">Login</button><br>
<input type="checkbox" class="filled-in" id="linux" value="linux" />
<label for="linux">Linuxの方はチェックをいれてください。</label><br>
Linuxでご使用の方はチェックを入れて下さい。<br>
<input type="checkbox" class="filled-in" id="linux" />
<label for="linux">コードセットアップ</label><br>
<span style="font-family:Open Sans;">Supports</span>
<div id="support"></div>
</div>

View File

@ -37,6 +37,9 @@ option {
position: fixed;
z-index: 9;
}
#imagemodal, #videomodal, #tootmodal {
background-color: white;
}
#imagemodal .modal-content {
overflow: hidden;
}
@ -134,7 +137,28 @@ blockquote:before, .quote:before {
font-size: 2rem;
}
.radio{
font-family:'Yanone Kaffeesatz'
font-family:'Baloo Bhai'
}
#pip{
z-index:1001;
width:418px;
background-color: white;
position:absolute;
}
.pip-bottom{
bottom:10px;
}
.pip-left{
left:10px;
}
.pip-top{
top:10px;
}
.pip-right{
right:10px;
}
#pip-content .material-icons{
display:none;
}
@media only screen and (min-width: 993px){
@ -173,7 +197,7 @@ blockquote:before, .quote:before {
justify-content: center;
align-items: center;
}
.blacktheme #imagemodal, #videomodal, #tootmodal {
.blacktheme #imagemodal,.blacktheme #videomodal,.blacktheme #tootmodal {
background-color: black;
}
.blacktheme .collapsible-header {
@ -182,6 +206,9 @@ blockquote:before, .quote:before {
.blacktheme .tabs {
background-color: #212121;
}
.blacktheme #pip {
background-color: #212121;
}
/*スクロールバー*/
::-webkit-scrollbar {

View File

@ -28,6 +28,9 @@ iframe {
flex: 1;
border: thin solid gray;
}
.box .pin{
display:none;
}
.user{
cursor:text;
font-size:1.2rem;
@ -118,7 +121,6 @@ font-size:1rem;
.toot-img {
object-fit: cover;
width: 100%;
height: 200px;
}
.toot img:not(.emoji-img) {
max-width: 100%;
@ -148,6 +150,9 @@ p {
.shared {
background-color: #cfd8dc;
}
.emphasized {
background-color: #81c784;
}
.udg {
cursor: pointer;
}
@ -165,6 +170,10 @@ p {
grid-template-rows: 30px 30px;
grid-template-areas: 'notice notice_name notice_name notice_name notice_name notice_name' 'notice a1 a2 a3 a4 a5' 'notf-box notf-box notf-box notf-box notf-box notf-box';
}
.emp{
font-weight: bold;
text-decoration: underline;
}
.area-notice {
grid-area: notice;
@ -269,3 +278,6 @@ p {
.blacktheme .notice-box {
background-color: #333333;
}
.blacktheme .emphasized {
background-color: #4e342e;
}

BIN
app/img/osushi_qr.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

View File

@ -10,7 +10,7 @@
<link href='./css/userdata.css' rel='stylesheet' type='text/css'>
<link href='./css/post.css' rel='stylesheet' type='text/css'>
<link href="./css/master.css" type="text/css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Open+Sans:300|Yanone+Kaffeesatz" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons|Open+Sans:300|Baloo+Bhai" rel="stylesheet">
<meta charset="utf-8">
</head>
<body>
@ -24,7 +24,7 @@
<script type="text/javascript" src="./js/common/modal.js"></script>
<script>
//トゥートリンク追加
var ver="Riina (ver.8)";
var ver="Airi (ver.1)";
//betaを入れるとバージョンチェックしない
//var ver="beta";
var acct_id=0;
@ -38,8 +38,9 @@ var tlid=0;
<input type="text" id="url" style="width:70%" placeholder="mstdn.jp">
<div id="ins-suggest"></div>
<button class="btn waves-effect" onclick="instance()">Login</button><br>
Linuxでご使用の方はチェックを入れて下さい。<br>
<input type="checkbox" class="filled-in" id="linux" />
<label for="linux">Linuxの方はチェックをいれてください。</label><br>
<label for="linux">コードセットアップ</label><br>
<span style="font-family:Open Sans;">Supports</span>
<div id="support">
</div>
@ -107,6 +108,7 @@ var tlid=0;
<div id="post-box" class="z-depth-3">
<!--トゥートボックス-->
<span class="cancel">
<i class="material-icons waves-effect" onclick="nano()" title="最小のマストドン。TheDesk Nano">remove_from_queue</i>
<i class="material-icons waves-effect" onclick="hide()" title="このボックスを閉じる(X)">cancel</i>
<i class="material-icons waves-effect mini-btn" onclick="mini()" title="このボックスを最小化">expand_more</i>
</span><br>
@ -118,13 +120,17 @@ var tlid=0;
<a onclick="profShow()"><i class="material-icons nex pointer mize waves-effect" title="選択中のプロフィール表示">account_circle</i></a>
<a href="index.html" class="setting nex mize waves-effect"><i class="material-icons nex" title="スーパーリロード">refresh</i></a>
<a onclick="window.open('https://astarte.thedesk.top');" class="setting nex mize waves-effect" target="_blank" id="ranking-btn" style="display:none;"><i class="material-icons nex" title="アスタルテランキング">timeline</i></a>
<a onclick="Rtoggle()" class="setting nex mize waves-effect" id="radio-btn"><i class="material-icons nex" title="Radio(Select/Pause)">play_circle_outline</i></a><span id="radio-sta" class="radio"></span>
<a onclick="Rtoggle()" class="setting nex mize waves-effect" id="radio-btn"><i class="material-icons nex" title="Radio(Select/Pause)">play_circle_outline</i></a>
<div id="waveform"></div>
<span id="radio-sta" class="radio"></span>
<div id="radio-view" class="hide radio mize">
<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://89.16.185.174:8004/stream','Linn Classical')" data-name="Linn Classical">Linn Classical</span>
<span class="cbadge pointer waves-effect" onclick="Rplay('http://89.16.185.174:8000/stream','Linn Jazz')" data-name="Linn Jazz">Linn Jazz</span>
<span class="cbadge pointer waves-effect" onclick="Rplay('http://edge-ads-01-cr.sharp-stream.com/jazzfmmobile.aac','Jazz FM')" data-name="Jazz FM">Jazz FM</span>
<span class="cbadge pointer waves-effect" onclick="Rplay('http://91.121.59.45:10024/stream','canal-jazz.eu')" data-name="canal-jazz.eu">canal-jazz.eu</span>
<span class="cbadge pointer waves-effect" onclick="Ryourself()">Others</span>
</div>
<div id="radio-input" class="hide radio mize">
@ -272,6 +278,7 @@ var tlid=0;
<div id="toot-after"></div>
</div>
<div class="modal-footer">
<a href="#!" class="waves-effect waves-green btn-flat" onclick="shot()">スクリーンショット</a>
<a href="#!" class="waves-effect waves-green btn-flat" onclick="cbCopy()">URLをコピー</a>
<a href="#!" class="waves-effect waves-green btn-flat" onclick="cbCopy('emb')">埋め込む</a>
<a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Close</a>
@ -348,6 +355,7 @@ var tlid=0;
<a href="#!" class="modal-action waves-effect waves-green btn-flat" id="his-follow-btn" onclick="follow()">フォロー</a>
<a href="#!" class="modal-action waves-effect waves-green btn-flat" id="his-mute-btn" onclick="mute()">ミュート</a>
<a href="#!" class="modal-action waves-effect waves-green btn-flat" id="his-block-btn" onclick="block()">ブロック</a>
<a href="#!" class="modal-action waves-effect waves-green btn-flat" id="his-emp-btn" onclick="empUser()">ユーザー強調</a>
<a href="#!" class="modal-action waves-effect waves-green btn-flat" onclick="hisclose()">Close</a>
</div>
</div>
@ -377,6 +385,12 @@ var tlid=0;
<a href="#!" class="modal-action modal-close waves-effect waves-green btn-flat">Close</a>
</div>
</div>
<!--PiP-->
<div id="pip" class="hide pip-bottom pip-left">
<i class="material-icons pip-horiz pointer" onclick="pipHoriz()">chevron_right</i> <i class="material-icons pip-vert pointer" onclick="pipVert()">expand_less</i>
 <i class="material-icons pointer" onclick="endPip()">close</i>
<div id="pip-content"></div>
</div>
<!--左下メッセージ-->
<div id="message"></div>
<!--Radio-->
@ -392,12 +406,14 @@ var tlid=0;
<script type="text/javascript" src="./js/tl/mix.js"></script>
<script type="text/javascript" src="./js/tl/src.js"></script>
<script type="text/javascript" src="./js/tl/filter.js"></script>
<script type="text/javascript" src="./js/tl/tag.js"></script>
<script type="text/javascript" src="./js/ui/layout.js"></script>
<script type="text/javascript" src="./js/login/login.js"></script>
<script type="text/javascript" src="./js/login/instance.js"></script>
<script type="text/javascript" src="./js/ui/post-box.js"></script>
<script type="text/javascript" src="./js/ui/img.js"></script>
<script type="text/javascript" src="./js/ui/theme.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/post/post.js"></script>
<script type="text/javascript" src="./js/post/reply.js"></script>

View File

@ -32,7 +32,7 @@ function ck() {
ck();
//ログインポップアップ
function login(url) {
if($('#linux:checked').val()=="linux"){
if($('#linux:checked').val()=="on"){
var red = "urn:ietf:wg:oauth:2.0:oob"
}else{
var red = 'thedesk://login';
@ -58,7 +58,7 @@ function login(url) {
}).then(function(json) {
var auth = "https://" + url + "/oauth/authorize?client_id=" + json[
"client_id"] + "&client_secret=" + json["client_secret"] +
"&response_type=code&redirect_uri=thedesk://login&scope=read+write+follow";
"&response_type=code&redirect_uri="+red+"&scope=read+write+follow";
localStorage.setItem("domain_" + acct_id, url);
localStorage.setItem("client_id", json["client_id"]);
localStorage.setItem("client_secret", json["client_secret"]);
@ -69,9 +69,14 @@ function login(url) {
} = require('electron');
shell.openExternal(auth);
if($('#linux:checked').val()=="on"){
}else{
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('quit', 'go');
}
});
}

View File

@ -99,6 +99,9 @@ function multiDel(target) {
obj.splice(target, 1);
var json = JSON.stringify(obj);
localStorage.setItem("multi", json);
Object.keys(obj).forEach(function(key) {
refresh(key);
});
load();
}
}
@ -145,7 +148,7 @@ function login(url) {
if (ng) {
return;
}
if($('#linux:checked').val()=="linux"){
if($('#linux:checked').val()=="on"){
var red = "urn:ietf:wg:oauth:2.0:oob"
}else{
var red = 'thedesk://manager';
@ -172,7 +175,7 @@ function login(url) {
console.log(json);
var auth = "https://" + url + "/oauth/authorize?client_id=" + json[
"client_id"] + "&client_secret=" + json["client_secret"] +
"&response_type=code&scope=read+write+follow&redirect_uri="+json.redirect_uri;
"&response_type=code&scope=read+write+follow&redirect_uri="+red;
localStorage.setItem("domain_tmp", url);
localStorage.setItem("client_id", json["client_id"]);
localStorage.setItem("client_secret", json["client_secret"]);
@ -185,7 +188,7 @@ function login(url) {
shell.openExternal(auth);
var electron = require("electron");
var ipc = electron.ipcRenderer;
if($('#linux:checked').val()=="linux"){
if($('#linux:checked').val()=="on"){
}else{
ipc.send('quit', 'go');
}

View File

@ -72,6 +72,13 @@
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
});
};
function escapeHTML(str) {
return str.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
//コピー
function execCopy(string){
var temp = $("#copy");
@ -80,3 +87,10 @@
var result = document.execCommand('copy');
return result;
}
//Nano
//Nano
function nano(){
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('nano', "");
}

134
app/js/platform/nano.js Normal file
View File

@ -0,0 +1,134 @@
//TL取得
function tl(data) {
var tlid=0;
var acct_id = $("#post-acct-sel").val();
var type = $("#type-sel").val();
var domain = localStorage.getItem("domain_" + acct_id);
//タグの場合はカラム追加して描画
if (!type) {
//デフォルト
var type = "local";
}
var at = localStorage.getItem(domain + "_at");
$("#notice_nano").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) {
console.error(error);
}).then(function(json) {
var templete = parse([json[0]], '', acct_id, tlid);
$("#timeline_nano").html(templete);
jQuery("time.timeago").timeago();
reload(type, '', acct_id, data);
});
}
//Streaming接続
var websocket=[];
function reload(type, cc, acct_id, data) {
var tlid=0;
var domain = localStorage.getItem("domain_" + acct_id);
var at = localStorage.getItem(domain + "_at");
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;
} else if (type == "tag") {
var start = "wss://" + domain +
"/api/v1/streaming/?stream=hashtag&tag=" + data +"&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);
$("#notice_icon_" + tlid).removeClass("red-text");
}
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=" + JSON.parse(mess.data).payload + "]").hide();
$("[toot-id=" + JSON.parse(mess.data).payload + "]").remove();
} else if (typeA == "update") {
var obj = JSON.parse(JSON.parse(mess.data).payload);
console.log(obj);
var templete = parse([obj], '', acct_id, tlid);
$("#timeline_nano").html(templete);
}
websocket[wsid].onclose = function(mess) {
console.log("Close Streaming API:" + type);
}
}
websocket[wsid].onerror = function(error) {
console.error('WebSocket Error ' + error);
};
}
//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 + "?"
}
}
//TLのアイコン
function icon(type) {
if (type == "home") {
return "home"
} else if (type == "local") {
return "people_outline"
} else if (type == "pub") {
return "language"
} else if (type == "tag") {
return "search"
}
if (type == "list") {
return "subject"
}
}
function todo(){}
function todc(){}

View File

@ -0,0 +1,56 @@
var electron = require("electron");
const fs = require("fs");
const os = require('os')
const shell = electron.shell;
const path = require('path')
function shot(){
//screenshotMsg.textContent = 'Gathering screens...'
$(window).height
let options = {
types: ['screen'],
thumbnailSize: {
width: window.parent.screen.width,
height: window.parent.screen.height
}
}
const desktopCapturer = electron.desktopCapturer;
desktopCapturer.getSources(options, function(error, sources) {
if (error) return console.log(error)
sources.forEach(function(source) {
if(location.search){
var m = location.search.match(/\?id=([a-zA-Z-0-9]+)/);
var title=m[1];
}else{
var title="screenshot";
}
if (source.name === 'Screen 1' || source.name === 'TheDesk') {
var durl=source.thumbnail.toDataURL();
var b64 = durl.match(
/data:image\/png;base64,(.+)/
);
const screenshotPath = path.join(os.tmpdir(), 'screenshot.png');
const savePath = path.join(os.tmpdir(), 'screenshot.png');
var ipc = electron.ipcRenderer;
var h = $(window).height()-150;
var w = $(window).width();
ipc.send('shot', ['file://' + screenshotPath,w,h,b64[1],title]);
if($(".img-parsed").length>0){
for(i=0;i<$(".img-parsed").length;i++){
var url=$(".img-parsed").eq(i).attr("data-url");
ipc.send('shot-img-dl', [url,title+"_img"+i+".png"]);
}
}
window.close();
return;
const message = `Saved screenshot to: ${screenshotPath}`
//screenshotMsg.textContent = message
}
})
})
}
$(window).load(function(){
setTimeout(function(){
shot();
},2000);
});

View File

@ -235,6 +235,39 @@ function del(id, acct_id) {
//$("#pub_"+id).hide();
});
}
//ピン留め
function pin(id, acct_id) {
if ($("#pub_" + id).hasClass("pined")) {
var flag = "unpin";
} else {
var flag = "pin";
}
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);
if ($("[toot-id=" + id +"]").hasClass("pined")) {
$("[toot-id=" + id +"]").removeClass("pined");
$(".pin_" + id).removeClass("blue-text");
} else {
$("[toot-id=" + id +"]").addClass("pined");
$(".pin_" + id).addClass("blue-text");
}
});
}
//フォロリク
function request(id, flag, acct_id) {
@ -289,6 +322,32 @@ function addDomainblock() {
var domain = $("#domainblock").val();
domainblock(domain, 'POST');
}
//ユーザー強調
function empUser(){
var usr = localStorage.getItem("user_emp");
var obj = JSON.parse(usr);
var id=$("#his-acct").attr("fullname");
console.log(id);
if(!obj){
var obj=[];
obj.push(id);
Materialize.toast(id+"を強調します。設定を適用するにはF5を押して下さい。", 4000);
}else{
var can;
Object.keys(obj).forEach(function(key) {
var usT = obj[key];
if(usT!=id && !can){
can=false;
}else{
can=true;
obj.splice(key, 1);
Materialize.toast(id+"の強調を解除しました。設定を適用するにはF5を押して下さい。", 4000);
}
});
}
var json = JSON.stringify(obj);
localStorage.setItem("user_emp", json);
}
//URLコピー
function tootUriCopy(url){
execCopy(url);

View File

@ -68,4 +68,5 @@ input.addEventListener("focus", function() {
input.addEventListener("blur", function() {
window.clearInterval(timer);
favTag();
}, false);

View File

@ -39,8 +39,7 @@ function additional(acct_id, tlid) {
json.description + "</span>");
}
if (json.html) {
$("[toot-id=" + id + "] .additional").html(json.html);
$("[toot-id=" + id + "] .additional").html(json.html+'<i class="material-icons" onclick="pip('+id+')">picture_in_picture_alt</i>');
}
if (json.title) {
$("[toot-id=" + id + "] a:not(.parsed)").addClass("parsed");
@ -100,7 +99,7 @@ function additionalIndv(tlid, acct_id, id) {
json.description + "</span>");
}
if (json.html) {
$("[toot-id=" + id + "] .additional").html(json.html);
$("[toot-id=" + id + "] .additional").html(json.html+'<i class="material-icons sml pointer" onclick="pip(\''+id+'\')" title="ながら観モード">picture_in_picture_alt</i>');
}
if (json.title) {

View File

@ -1,7 +1,7 @@
//トゥートの詳細
function details(id, acct_id) {
function details(id, acct_id, tlid) {
$(".toot-reset").html("データなし");
var html = $("#pub_" + id).html();
var html = $("#timeline_"+tlid+" #pub_" + id).html();
$("#toot-this").html(html);
$('#tootmodal').modal('open');
var domain = localStorage.getItem("domain_" + acct_id);
@ -22,6 +22,7 @@ function details(id, acct_id) {
$("#toot-this .fav_ct").text(json.favourites_count);
$("#toot-this .rt_ct").text(json.reblogs_count);
$("#tootmodal").attr("data-url",json.url);
$("#tootmodal").attr("data-id",json.id);
if (json.in_reply_to_id) {
replyTL(json.in_reply_to_id, acct_id);
}
@ -168,3 +169,14 @@ function cbCopy(mode){
}
}
//魚拓
function shot(){
var id=$("#tootmodal").attr("data-id");
var w=$("#toot-this").width();
var h=$("#toot-this").height()+150;
var text=$("#toot-this").html();
localStorage.setItem("sc-text",text)
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('screen', [w,h,id]);
}

View File

@ -27,6 +27,7 @@ function mixtl(acct_id, tlid) {
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";
@ -43,32 +44,46 @@ function mixtl(acct_id, tlid) {
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[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(locals).forEach(function(key2) {
if (!$("#timeline_" + tlid + " [toot-id=" + obj[0].id + "]").length &&
key2 < date(obj[0].created_at, 'unix')) {
$("#timeline_" + tlid + " .cvo").first().before(parse([obj[0]],
'home', acct_id, tlid)+'<div class="divider"></div>');
}
if (!$("#timeline_" + tlid + " [toot-id=" + toot.id + "]").length) {
if (key2 > tarunix) {
var local = locals[key2];
console.log("#timeline_" + tlid + " [toot-id=" + local + "]");
$("#timeline_" + tlid + " [toot-id=" + local + "]").after('<div class="divider"></div>'+parse(
[toot], 'home', acct_id, tlid));
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);
@ -94,9 +109,11 @@ function mixre(acct_id, tlid) {
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:");
@ -164,6 +181,7 @@ function mixmore(tlid) {
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);
@ -197,9 +215,10 @@ function mixmore(tlid) {
todo(error);
console.error(error);
}).then(function(obj) {
if (!$("[toot-id=" + obj[0].id + "]").length) {
$("#timeline_" + tlid + " .cvo").first().before(parse([obj[0]], 'home',
acct_id));
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;
@ -209,12 +228,12 @@ function mixmore(tlid) {
var beforekey2;
var key2;
Object.keys(locals).forEach(function(key2) {
if (!$("[toot-id=" + toot.id + "]").length) {
if ($("[toot-id=" + toot.id + "]").length <1) {
if (key2 > tarunix) {
var local = locals[key2];
$("[toot-id=" + local + "]").after(parse([toot], 'home',
$("#timeline_" + tlid + " [toot-id=" + local + "]").after(parse([toot], 'home',
acct_id, tlid));
tarunix = 0;
tarunix = 2147483647;
}
}

View File

@ -60,17 +60,16 @@ function notf(acct_id, tlid, sys) {
if (!popup) {
popup = 0;
}
if(json.type!="follow"){
templete = templete+parse([json], '', acct_id, tlid, popup);
var templete="";
if(obj.type!="follow"){
templete = templete+parse([obj], '', acct_id, tlid, popup);
}else{
templete = templete+userparse([json], '', acct_id, tlid, popup);
templete = templete+userparse([obj], '', acct_id, tlid, popup);
}
var notices = templete[1];
console.log(templete);
if (sys == "direct") {
$("#timeline_" + tlid).prepend(templete[0]);
$("#timeline_" + tlid).prepend(templete);
} else {
$("#notifications_" + tlid).prepend(templete[0]);
$("#notifications_" + tlid).prepend(templete);
}
jQuery("time.timeago").timeago();
} else if (type == "delete") {

View File

@ -6,6 +6,32 @@ function parse(obj, mix, acct_id, tlid, popup) {
var sent = localStorage.getItem("sentence");
var ltr = localStorage.getItem("letters");
var gif = localStorage.getItem("gif");
var imh = localStorage.getItem("img-height");
//クライアント強調
var emp = localStorage.getItem("client_emp");
if(emp){
var emp = JSON.parse(emp);
}
//クライアントミュート
var mute = localStorage.getItem("client_mute");
if(mute){
var mute = JSON.parse(mute);
}
//ユーザー強調
var useremp = localStorage.getItem("user_emp");
if(useremp){
var useremp = JSON.parse(useremp);
}
//ワード強調
var wordemp = localStorage.getItem("word_emp");
if(wordemp){
var wordemp = JSON.parse(wordemp);
}
//ワードミュート
var wordmute = localStorage.getItem("word_mute");
if(wordmute){
var wordmute = JSON.parse(wordmute);
}
if (!sent) {
var sent = 500;
}
@ -29,7 +55,27 @@ function parse(obj, mix, acct_id, tlid, popup) {
if (!gif) {
var gif = "yes";
}
if (!imh) {
var imh = "200";
}
if(!emp){
var emp=[];
}
if(!mute){
var mute=[];
}
if(!useremp){
var useremp=[];
}
if(!wordemp){
var wordemp=[];
}
if(!wordmute){
var wordmute=[];
}
var local = [];
var times=[];
Object.keys(obj).forEach(function(key) {
var toot = obj[key];
if(popup){
@ -47,7 +93,6 @@ function parse(obj, mix, acct_id, tlid, popup) {
'\',\'' + acct_id + '\')" class="pointer">' + toot.account.display_name +
"(" + toot.account.acct +
")</a>が" + what;
var toot = toot.status;
var notice = noticetext;
var memory = localStorage.getItem("notice-mem");
if (popup >= 0 && obj.length < 5 && noticetext != memory) {
@ -56,6 +101,7 @@ function parse(obj, mix, acct_id, tlid, popup) {
localStorage.setItem("notice-mem", noticetext);
noticetext = "";
}
var toot = toot.status;
}else{
if (toot.reblog) {
var notice = toot.account.display_name + "(" + toot.account.acct +
@ -65,17 +111,34 @@ function parse(obj, mix, acct_id, tlid, popup) {
} else {
var notice = "";
var boostback = "";
//ユーザー強調
if(toot.account.username!=toot.account.acct){
var fullname=toot.account.acct;
}else{
var domain = localStorage.getItem("domain_" + acct_id);
var fullname=toot.account.acct+"@"+domain;
}
if(useremp){
console.log(useremp);
Object.keys(useremp).forEach(function(key10) {
var user = useremp[key10];
if(user==fullname){
boostback = "emphasized";
}
});
}
}
}
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") {
var home = "Home TLより"
var divider = "";
var divider = '<div class="divider"></div>';
} else {
var home = "";
var divider = '<div class="divider"></div>';
@ -89,6 +152,20 @@ function parse(obj, mix, acct_id, tlid, popup) {
var via = '<span style="font-style: italic;">Unknown</span>';
} else {
var via = toot.application.name;
//強調チェック
Object.keys(emp).forEach(function(key6) {
var cli = emp[key6];
if(cli == via){
boostback = "emphasized";
}
});
//ミュートチェック
Object.keys(mute).forEach(function(key7) {
var cli = mute[key7];
if(cli == via){
boostback = "hide";
}
});
}
if (toot.spoiler_text && cw) {
var content = toot.content;
@ -157,7 +234,7 @@ function parse(obj, mix, acct_id, tlid, popup) {
acct_id + ')" id="' + id + '-image-' + key2 + '" data-url="' + url +
'" data-type="' + media.type + '" class="img-parsed"><img src="' +
purl + '" class="' + sense +
' toot-img pointer" style="width:' + cwdt + '%"></a></span>';
' toot-img pointer" style="width:' + cwdt + '%; height:'+imh+'px;"></a></span>';
});
} else {
viewer = "";
@ -184,8 +261,9 @@ function parse(obj, mix, acct_id, tlid, popup) {
}
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> ';
tags = tags + '<a onclick="tagShow(\'' + tag.name + '\')" class="pointer">#' + tag.name + '</a><span class="hide" data-tag="' + tag.name + '"> <a onclick="tl(\'tag\',\'' + tag.name + '\',' + acct_id +
',\'add\')" class="pointer" title="#' + tag.name + 'のタイムライン">TL</a> <a onclick="brInsert(\'#' + tag.name + '\')" class="pointer" title="#' + tag.name + 'でトゥート">Toot</a> '+
'<a onclick="tagPin(\'' + tag.name + '\')" class="pointer" title="#' + tag.name + 'をよく使うタグへ">Pin</a></span> ';
});
tags = '<div style="float:right">' + tags + '</div>';
}
@ -228,14 +306,45 @@ function parse(obj, mix, acct_id, tlid, popup) {
var if_rt = "";
var rt_app = "";
}
if (toot.pinned) {
var if_pin = "blue-text";
var pin_app = "pinned";
} else {
var if_pin = "";
var pin_app = "";
}
//アニメ再生
if (gif == "yes") {
var avatar = toot.account.avatar;
} else {
var avatar = toot.account.avatar_static;
}
//ワードミュート
if(wordmute){
Object.keys(wordmute).forEach(function(key8) {
var worde = wordmute[key8];
if(worde){
var word=worde.tag;
var regExp = new RegExp( word, "g" ) ;
if(content.match(regExp)){
boostback = "hide";
}
}
});
}
//ワード強調
if(wordemp){
Object.keys(wordemp).forEach(function(key9) {
var word = wordemp[key9];
if(word){
var word=word.tag;
var regExp = new RegExp( word, "g" ) ;
content=content.replace(regExp,'<span class="emp">'+word+"</span>");
}
});
}
templete = templete + '<div id="pub_' + toot.id + '" class="cvo ' +
boostback + ' ' + fav_app + ' ' + rt_app +
boostback + ' ' + fav_app + ' ' + rt_app + ' ' + pin_app +
' ' + hasmedia + '" toot-id="' + id + '" unixtime="' + date(obj[
key].created_at, 'unix') + '">' +
'<div class="area-notice"><span class="gray sharesta">' + notice + home +
@ -246,7 +355,7 @@ function parse(obj, mix, acct_id, tlid, popup) {
'" width="40" class="prof-img" user="' + toot.account.acct +
'"></a></div>' +
'<div class="area-display_name"><span class="user">' +
toot.account.display_name +
escapeHTML(toot.account.display_name) +
'</span><span class="sml gray" style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis; cursor:text;"> @' +
toot.account.acct + locked + '</span></div>' +
'<div class="area-acct"><div><span class="cbadge pointer waves-effect" onclick="tootUriCopy(\'' +
@ -266,30 +375,33 @@ function parse(obj, mix, acct_id, tlid, popup) {
vis + '</span></div><div class="action"><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>' +
')" class="waves-effect waves-dark btn-flat" style="padding:0" title="このトゥートに返信"><i class="fa fa-share"></i></a></div>' +
'<div class="action '+can_rt+'"><a onclick="rt(\'' + toot.id + '\',' + acct_id +
',\'' + tlid +
'\')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="text-darken-3 fa fa-retweet ' +
'\')" 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"><a onclick="fav(\'' + toot.id + '\',' + acct_id +
',\'' + tlid +
'\')" class="waves-effect waves-dark btn-flat" style="padding:0"><i class="fa text-darken-3 fa-star' +
'\')" 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"><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>' +
')" 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"><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>' +
'<div class="action"><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>' +
','+tlid+')" 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="area-date_via">' +
'<div><span class="cbadge" title="via ' + $.strip_tags(via) + '">via ' +
'<div><span class="cbadge waves-effect" onclick="client(\''+$.strip_tags(via)+'\')" title="via ' + $.strip_tags(via) + '">via ' +
via +
'</span></div></div></div>' +
'</div>' + divider;
});
if (mix == "mix") {
return [templete, local]
return [templete, local, times]
} else {
return templete;
}
@ -351,3 +463,64 @@ function userparse(obj, auth, acct_id, tlid, popup) {
});
return templete;
}
//クライアントダイアログ
function client(name) {
if(name!="Unknown"){
//聞く
localStorage.removeItem("client_mute");
var electron = require("electron");
var remote=electron.remote;
var dialog=remote.dialog;
const options = {
type: 'info',
title: 'クライアント処理',
message: name+"に対する処理を選択してください。",
buttons: ['何もしない','強調表示/解除', 'ミュート']
}
dialog.showMessageBox(options, function(arg) {
if(arg==1){
var cli = localStorage.getItem("client_emp");
var obj = JSON.parse(cli);
if(!obj){
var obj=[];
obj.push(name);
Materialize.toast(name+"を強調表示します。", 2000);
}else{
var can;
Object.keys(obj).forEach(function(key) {
var cliT = obj[key];
if(cliT!=name && !can){
can=false;
}else{
can=true;
obj.splice(key, 1);
Materialize.toast(name+"の強調表示を解除しました。", 2000);
}
});
if(!can){
obj.push(name);
Materialize.toast(name+"を強調表示します。", 2000);
}else{
}
}
var json = JSON.stringify(obj);
localStorage.setItem("client_emp", json);
}else if(arg==2){
var cli = localStorage.getItem("client_mute");
var obj = JSON.parse(cli);
if(!obj){
var obj=[];
}
obj.push(name);
var json = JSON.stringify(obj);
localStorage.setItem("client_mute", json);
Materialize.toast(name+"をミュートします。設定から削除できます。", 2000);
}else{
return;
}
parseColumn();
})
}
}

60
app/js/tl/tag.js Normal file
View File

@ -0,0 +1,60 @@
//よく使うタグ
function tagShow(tag){
$("[data-tag="+tag+"]").toggleClass("hide");
}
//タグ追加
function tagPin(tag){
var tags = localStorage.getItem("tag");
if(!tags){
var obj=[];
}else{
var obj = JSON.parse(tags);
}
var can;
Object.keys(obj).forEach(function(key) {
var tagT = obj[key];
if(tagT==tag){
can=true;
}else{
can=false;
}
});
if(!can){
obj.push(tag);
}
var json = JSON.stringify(obj);
localStorage.setItem("tag", json);
favTag();
}
//タグ削除
function tagRemove(key) {
var tags = localStorage.getItem("tag");
var obj = JSON.parse(tags);
obj.splice(key, 1);
var json = JSON.stringify(obj);
localStorage.setItem("tag", json);
favTag();
}
function favTag(){
var tagarr = localStorage.getItem("tag");
if(!tagarr){
var obj=[];
}else{
var obj = JSON.parse(tagarr);
}
var tags="";
Object.keys(obj).forEach(function(key) {
var tag = obj[key];
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> '+
'<a onclick="tagRemove(\'' + key + '\')" class="pointer" title="#' + tag + 'をよく使うタグから削除">Unpin</a></span> ';
});
if(obj.length>0){
$("#suggest").html("My Tags:" + tags);
}else{
$("#suggest").html("");
}
}
function tagTL(a,b,c,d){
var acct_id = $("#post-acct-sel").val();
tl(a,b,acct_id,d);
}

View File

@ -101,6 +101,7 @@ function reload(type, cc, acct_id, tlid, data) {
websocket[wsid].onopen = function(mess) {
console.log(tlid + ":Connect Streaming API:" + type);
console.log(mess);
$("#notice_icon_" + tlid).removeClass("red-text");
}
websocket[wsid].onmessage = function(mess) {
console.log(tlid + ":Receive Streaming API:");
@ -115,6 +116,7 @@ function reload(type, cc, acct_id, tlid, data) {
} else if (typeA == "update") {
var obj = JSON.parse(JSON.parse(mess.data).payload);
console.log(obj);
if($("#timeline_" + tlid +" [toot-id=" + obj.id + "]").length < 1){
var templete = parse([obj], '', acct_id, tlid);
var pool = localStorage.getItem("pool_" + tlid);
if (pool) {
@ -128,6 +130,10 @@ function reload(type, cc, acct_id, tlid, data) {
additional(acct_id, tlid);
jQuery("time.timeago").timeago();
}else{
todo("二重取得発生中");
}
todc();
}
websocket[wsid].onclose = function(mess) {

View File

@ -271,7 +271,7 @@ function dlImg(){
var url=$("#imgmodal").attr("src");
var electron = require("electron");
var ipc = electron.ipcRenderer;
ipc.send('general-dl', url);
ipc.send('general-dl', [url,false]);
ipc.on('general-dl-prog', function (event, arg) {
console.log(arg);
})

View File

@ -63,7 +63,7 @@
var acct = obj[key];
var html = '<div class="box" id="timeline_box_' + key + '_box" tlid="' + key +
'"><div class="notice-box z-depth-2">'+
'<div class="area-notice"><i class="material-icons waves-effect" id="notice_icon_' + key + '" style="font-size:40px; padding-top:25%;" onclick="goTop(' + key + ')"></i></div>'+
'<div class="area-notice"><i class="material-icons waves-effect red-text" id="notice_icon_' + key + '" style="font-size:40px; padding-top:25%;" onclick="goTop(' + key + ')" title="アイコンが赤のときはストリーミングに接続できていません。F5等で再読込をお試し下さい。"></i></div>'+
'<div class="area-notice_name"><span id="notice_' + key + '"" class="tl-title"></span></div>'+
'<div class="area-a1"><a onclick="notfToggle(' + acct.domain + ',' + key +
')" class="setting nex" title="このアカウントの通知"><i class="material-icons waves-effect nex notf-icon_' +
@ -119,6 +119,7 @@
$("#vis").text(vis);
}
}
favTag();
}
//カラム追加
function addColumn() {

32
app/js/ui/pip.js Normal file
View File

@ -0,0 +1,32 @@
function pip(id){
$("#pip-content").html($("[toot-id=" + id + "] .additional").html());
$("#pip").removeClass("hide");
}
function endPip(){
$("#pip-content").html();
$("#pip").addClass("hide");
}
function pipHoriz(){
if($("#pip").hasClass("pip-left")){
$("#pip").removeClass("pip-left");
$(".pip-horiz").text("chevron_left");
$("#pip").addClass("pip-right");
}else{
$("#pip").addClass("pip-left");
$("#pip").removeClass("pip-right");
$(".pip-horiz").text("chevron_right");
}
}
function pipVert(){
if($("#pip").hasClass("pip-top")){
$("#pip").removeClass("pip-top");
$("#pip").addClass("pip-bottom");
$(".pip-vert").text("expand_less");
}else{
$("#pip").addClass("pip-top");
$("#pip").removeClass("pip-bottom");
$(".pip-vert").text("expand_more");
}
}

View File

@ -85,12 +85,21 @@ function settings() {
if (imgd != localStorage.getItem("img")) {
Materialize.toast("画像投稿後の設定を「" + imgt + "」に設定しました。", 3000);
}
localStorage.setItem("img", imgd);
var sized = $("#size").val();
if (sized != localStorage.getItem("size")) {
Materialize.toast("フォントサイズを" + sized + "pxに設定しました。", 3000);
}
localStorage.setItem("size", sized);
localStorage.setItem("img", imgd);
var heid = $("#img-height").val();
if (heid != localStorage.getItem("img-height")) {
Materialize.toast("画像高さを" + heid + "pxに設定しました。", 3000);
}
localStorage.setItem("img-height", heid);
}
//読み込み時の設定ロード
@ -180,8 +189,74 @@ function load() {
}
$("#size").val(size);
var imh = localStorage.getItem("img-height");
if (!imh) {
var imh = "200";
}
$("#img-height").val(imh);
//並べ替え
sortload();
}
//最初に読む
load();
climute();
wordmute();
wordemp();
function climute(){
//クライアントミュート
var cli = localStorage.getItem("client_mute");
var obj = JSON.parse(cli);
if(!obj){
$("#mute-cli").html("ミュートしているクライアントはありません。");
}else{
if(!obj[0]){
$("#mute-cli").html("ミュートしているクライアントはありません。");
return;
}
var templete;
Object.keys(obj).forEach(function(key) {
var cli = obj[key];
var list = key * 1 + 1;
templete = '<div class="acct" id="acct_' + key + '">' + list +
'.' +
cli + '<button class="btn waves-effect red disTar" onclick="cliMuteDel(' +
key + ')">削除</button><br></div>';
$("#mute-cli").append(templete);
});
}
}
function cliMuteDel(key){
var cli = localStorage.getItem("client_mute");
var obj = JSON.parse(cli);
obj.splice(key, 1);
var json = JSON.stringify(obj);
localStorage.setItem("client_mute", json);
mute();
}
function wordmute(){
var word = localStorage.getItem("word_mute");
var obj = JSON.parse(word);
$('#wordmute').material_chip({
data: obj,
});
}
function wordmuteSave(){
var word=$('#wordmute').material_chip('data');
var json = JSON.stringify(word);
localStorage.setItem("word_mute", json);
}
function wordemp(){
var word = localStorage.getItem("word_emp");
var obj = JSON.parse(word);
$('#wordemp').material_chip({
data: obj,
});
}
function wordempSave(){
var word=$('#wordemp').material_chip('data');
var json = JSON.stringify(word);
localStorage.setItem("word_emp", json);
}

View File

@ -51,14 +51,17 @@ function udg(user, acct_id) {
if(json.username!=json.acct){
//Remote
$('#his-data').attr("remote", "true");
var fullname=json.acct;
}else{
$('#his-data').attr("remote", "false");
var fullname=json.acct+"@"+domain;
}
utl(json.id, '', acct_id);
flw(json.id, '', acct_id);
fer(json.id, '', acct_id);
$("#his-name").text(json.display_name);
$("#his-acct").text(json.acct);
$("#his-acct").attr("fullname",fullname);
$("#his-prof").attr("src", json.avatar);
$('#his-data').css('background-image', 'url(' + json.header + ')');
$("#his-sta").text(json.statuses_count);
@ -85,6 +88,7 @@ function udg(user, acct_id) {
$("#his-mute-btn").hide();
$("#his-notf-btn").hide();
$("#his-domain-btn").hide();
$("#his-emp-btn").hide();
$("#my-data-nav").show();
$("#his-data-nav").hide();
} else {
@ -195,6 +199,7 @@ function reset(){
$("#his-mute-btn").show();
$("#his-notf-btn").show();
$("#his-domain-btn").show();
$("#his-emp-btn").show();
$("#his-follow-btn").text("フォロー");
$("#his-mute-btn").text("ミュート");
$("#his-block-btn").text("ブロック");

View File

@ -5,6 +5,9 @@ const electron = require("electron");
const fs = require("fs");
const dialog = require('electron').dialog;
var Jimp = require("jimp");
const shell = electron.shell;
const os = require('os')
const path = require('path')
// アプリケーションをコントロールするモジュール
const app = electron.app;
@ -41,7 +44,7 @@ function createWindow() {
electron.session.defaultSession.clearCache(() => {})
if(process.argv){
if(process.argv[1]){
var m = process.argv[1].match(/([a-zA-Z0-9]+)\/\?[a-zA-Z-0-9]+=([a-zA-Z-0-9]+)/);
var m = process.argv[1].match(/([a-zA-Z0-9]+)\/\?[a-zA-Z-0-9]+=(.+)/);
if(m){
var mode=m[1];
var code=m[2];
@ -80,19 +83,36 @@ ipc.on('update', function(e, x, y) {
return "true"
})
ipc.on('nano', function(e, x, y) {
ipc.on('screen', function(e, args) {
var window = new BrowserWindow({
width: 300,
height: 100,
"transparent": true, // ウィンドウの背景を透過
width: args[0],
height: args[1],
"transparent": false, // ウィンドウの背景を透過
"frame": false, // 枠の無いウィンドウ
"resizable": false
"resizable": true
});
window.loadURL('file://' + __dirname + '/nano.html');
window.loadURL('file://' + __dirname + '/screenshot.html?id='+args[2]);
window.setAlwaysOnTop(true);
window.setPosition(0, 0);
return "true"
})
//Web魚拓
ipc.on('shot', function(e, args) {
console.log(args[0]);
Jimp.read(Buffer.from( args[3],'base64'), function (err, lenna) {
if (err) throw err;
lenna.crop( 0, 0, args[1], args[2] ).write(app.getPath('home')+"\\Pictures\\TheDesk\\Screenshots\\"+args[4]+"-toot.png");
});
shell.showItemInFolder(app.getPath('home')+"\\Pictures\\TheDesk\\Screenshots\\");
})
ipc.on('shot-img-dl', (e, args) => {
Jimp.read(args[0], function (err, lenna) {
if (err) throw err;
lenna.write(app.getPath('home')+"\\Pictures\\TheDesk\\Screenshots\\"+args[1]);
});
});
//アプデDL
ipc.on('download-btn', (e, args) => {
if(args=="true"){
dialog.showSaveDialog(null, {
@ -143,10 +163,12 @@ function dl(files,fullname){
.catch(console.error);
}
ipc.on('general-dl', (e, args) => {
console.log(args)
var name="";
var dir=app.getPath('home')+"\\Pictures\\TheDesk";
mainWindow.webContents.send('general-dl-message', "ダウンロードを開始します。");
const opts = {
directory: app.getPath('home')+"\\Pictures\\TheDesk",
directory: dir,
filename:name,
openFolderWhenDone: true,
onProgress: function(e) {
mainWindow.webContents.send('general-dl-prog', e);
@ -154,7 +176,7 @@ ipc.on('general-dl', (e, args) => {
saveAs: false
};
download(BrowserWindow.getFocusedWindow(),
args, opts)
args[0], opts)
.then(dl => {
mainWindow.webContents.send('general-dl-message', "ダウンロードが完了しました。");
})
@ -195,4 +217,14 @@ ipc.on('bmp-image', (e, args) => {
});
});
ipc.on('nano', function (e, x, y) {
var window = 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"
})
app.setAsDefaultProtocolClient('thedesk')

98
app/nano.html Normal file
View File

@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="./css/tl.css" type="text/css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<title>TheDesk Nano</title>
<style>
body {
background-color: rgba(0, 0, 0, 0.1);
}
#drag{
-webkit-app-region: drag;
cursor: move;
}
button {
-webkit-app-region: no-drag;
}
textarea {
-webkit-app-region: no-drag;
}
::-webkit-scrollbar {
width: 5px;
height:10px;
background: rgba(0,0,0,0.05);
}
::-webkit-scrollbar-track {
-webkit-border-radius: 5px;
border-radius: 5px;
}
.area-actions{display:none !important;}
.area-date_via{display:none !important;}
/* Handle */
::-webkit-scrollbar-thumb {
-webkit-border-radius: 5px;
border-radius: 5px;
background: rgba(0,0,0,0.8);
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
}
</style>
</head>
<body>
<script type="text/javascript" src="./js/common/jquery.js"></script>
<script type="text/javascript" src="./js/platform/first.js"></script>
<div id="drag">+</div>
<span id="timeline_nano">
<select id="type-sel">
<option value="local">Local</option>
<option value="home">Home</option>
</select>
<button onclick="tl()">表示</button>
</span><br><button onclick="window.close()">終了</button><br>
<textarea id="textarea"></textarea>
<input type="hidden" id="reply">
<input type="hidden" id="media">
<select id="post-acct-sel">
</select>
<button class="btn" onclick="post()">投稿</button>
<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/tl/parse.js"></script>
<script type="text/javascript" src="./js/tl/date.js"></script>
<script type="text/javascript" src="./js/common/time.js"></script>
<script type="text/javascript" src="./js/platform/nano.js"></script>
<script type="text/javascript" src="./js/platform/end.js"></script>
<script>
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 + '" ' + sel + '>' + acct.user + '@' + acct.domain +
'</option>';
$("#post-acct-sel").append(templete);
});
</script>

View File

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

29
app/screenshot.html Normal file
View File

@ -0,0 +1,29 @@
<!doctype html>
<html lang="ja">
<head>
<title>TheDesk Screenshot</title>
<meta content="width=device-width,initial-scale=1.0" name="viewport">
<link href="./css/materialize.css" type="text/css" rel="stylesheet">
<link href="./css/auth.css" type="text/css" rel="stylesheet">
<link href='./css/font-awesome.css' rel='stylesheet' type='text/css'>
<link href='./css/tl.css' rel='stylesheet' type='text/css'>
<link href='./css/userdata.css' rel='stylesheet' type='text/css'>
<link href='./css/post.css' rel='stylesheet' type='text/css'>
<link href="./css/master.css" type="text/css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<meta charset="utf-8">
</head>
<body style="padding:5px;">
<script type="text/javascript" src="./js/common/jquery.js"></script>
<script type="text/javascript" src="./js/platform/first.js"></script>
<script type="text/javascript" src="./js/common/materialize.js"></script>
<div id="toot" class="cvo"></div>
<script>
//console.log(location.search);
$("#toot").html(localStorage.getItem("sc-text"));
localStorage.removeItem("sc-text");
</script>
<script type="text/javascript" src="./js/ui/theme.js"></script>
<script type="text/javascript" src="./js/platform/screenshot.js"></script><br>
<span style="position: absolute; bottom:0;">数秒お待ち下さい。完了後エクスプローラーが表示されます。</span>

View File

@ -61,7 +61,6 @@
<br>
<input type="text" style="width:50px" id="size">px
<button class="btn waves-effect" style="width:100px;" onclick="settings()">設定</button>
<br>
</div>
</li>
<li>
@ -106,6 +105,11 @@
<input type="text" style="width:50px" id="letters">文字以上
<button class="btn waves-effect" style="width:100px;" onclick="settings()">設定</button>
<br>
<h5>画像の高さ</h5>
<br>
<input type="text" style="width:50px" id="img-height">px
<button class="btn waves-effect" style="width:100px;" onclick="settings()">設定</button>
<br>
</div>
</li>
<li>
@ -150,6 +154,28 @@
<br>
</div>
</li>
<li>
<div class="collapsible-header">
<i class="material-icons">bookmark</i>ミュート・強調の設定
</div>
<div class="collapsible-body">
<h5>クライアントミュート</h5>
<div id="mute-cli"></div>
<h5>クライアント強調</h5>
各トゥートのクライアントをクリックすると設定できます。
<h5>ワードミュート</h5>
Enterで確定<br>
<div class="chips" id="wordmute" style="background-color:gray;"></div>
<button onclick="wordmuteSave()" class="btn waves-effect" style="width:100px;">設定</button>
<h5>ワード強調</h5>
Enterで確定<br>
<div class="chips" id="wordemp" style="background-color:gray;"></div>
<button onclick="wordempSave()" class="btn waves-effect" style="width:100px;">設定</button>
<h5>ユーザー強調</h5>
各ユーザーのデータ表示画面で設定できます。
<span class="emphasized"> 強調色(テーマによって異なります。) </span>
</div>
</li>
</ul>
<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>
@ -194,6 +220,9 @@
<br>
<a href="https://enty.jp/Cutls" class="btn waves-effect purple lighten-2" style="width:100%; max-width:500px;"><i class="material-icons left">trending_up</i>寄付(Enty)</a>
<br>
寿司を投げる<br>
<a href="https://osushi.love/Cutls_P" target="_blank">Osushi.love</a>(スマートフォンから)<br>
<img src="./img/osushi_qr.png"><br>
<a href="https://github.com/cutls/TheDesk" class="btn waves-effect black lighten-2" style="width:100%; max-width:500px;"><i class="fa fa-github left"></i>GitHub</a>
<br>
<a href="index.html?mode=open&code=12336" class="btn waves-effect blue lighten-2" style="width:100%; max-width:500px;"><img src="./img/desk_full.svg" class="left" width="25" style="padding-top:5px;">Developer: Cutls@kirishima.cloud</a>

View File

@ -1 +1 @@
{"desk":"Riina (ver.8)","date":"2018-02-25","detail":"内部V:12.8.0|バグ修正。プラットフォーム追加。詳しくはGitHub参照"}
{"desk":"Airi (ver.1)","date":"2018-03-10","detail":"内部V:13.1.0|TheDesk史上最大の機能追加数。詳しくはGitHubやHP参照"}