WIP: Add: announcement(except: mark as read)

This commit is contained in:
cutls 2020-01-28 02:07:36 +09:00
parent ab265fae62
commit b642d42229
10 changed files with 345 additions and 82 deletions

View File

@ -490,6 +490,9 @@ textarea {
text-overflow: ellipsis;
overflow: hidden;
}
#sabakanMark {
background-color: var(--emphasized);
}
/*スクロールバー*/
::-webkit-scrollbar {

View File

@ -559,7 +559,7 @@ p:not(:last-child) {
z-index: 500;
padding: 5px;
display: grid;
grid-template-columns: 40px 1fr 1fr 24px;
grid-template-columns: 40px 60px 1fr 24px;
grid-template-rows: 30px 30px;
grid-template-areas: 'notice notice_name notice_name a2' 'notice a1 sta a3' 'notf-box notf-box notf-box notf-box';
}
@ -862,3 +862,31 @@ audio {
.box .ui-resizable-se {
display: none !important;
}
.announcement {
padding: 5px;
border-bottom: 1px solid;
}
.announReaction {
width: 35px;
height: 1.7rem;
font-size: 1.1rem;
margin: 3px;
cursor: pointer;
border: solid 1px;
padding-left: 2px;
background-color: var(--notfbox);
border-radius: 2px;
}
.announReaction img {
position: relative;
top: 3px;
}
.announReaction.reactioned {
background-color: var(--emphasized);
}
.announReaction.add {
width: 19px;
}
.reactionsPack {
display: flex;
}

View File

@ -1,84 +1,105 @@
var defaultemojiList = ["activity", "flag", "food", "nature", "object", "people", "place", "symbol"];
var defaultemojiList = ['activity', 'flag', 'food', 'nature', 'object', 'people', 'place', 'symbol']
var defaultemoji = {
activity: activity,
flag: flag,
food: food,
nature: nature,
object: object,
people: people,
place: place,
symbol: symbol
};
if (lang == "ja") {
var defaultemojiname = {
activity: "活動",
flag: "国旗",
food: "食べ物",
nature: "自然",
object: "もの",
people: "ひと",
place: "場所",
symbol: "記号"
};
activity: activity,
flag: flag,
food: food,
nature: nature,
object: object,
people: people,
place: place,
symbol: symbol
}
if (lang == 'ja') {
var defaultemojiname = {
activity: '活動',
flag: '国旗',
food: '食べ物',
nature: '自然',
object: 'もの',
people: 'ひと',
place: '場所',
symbol: '記号'
}
} else {
var defaultemojiname = {
activity: "Activities",
flag: "Flags",
food: "Foods",
nature: "Nature",
object: "Tools",
people: "People",
place: "Places",
symbol: "Symbols"
};
var defaultemojiname = {
activity: 'Activities',
flag: 'Flags',
food: 'Foods',
nature: 'Nature',
object: 'Tools',
people: 'People',
place: 'Places',
symbol: 'Symbols'
}
}
function defaultEmoji(target) {
var json = defaultemoji[target];
var emojis = "";
Object.keys(json).forEach(function (key) {
var emoji = json[key];
emojis = emojis + '<a onclick="defEmoji(\'' + emoji["shortcode"] + '\')" class="pointer"><span style="width: 20px; height: 20px; display: inline-block; background-image: url(\'../../img/sheet.png\'); background-size: 4900%; background-position: ' + emoji["css"] + ';"></span></a>';
});
$("#emoji-list").html(emojis);
$("#now-emoji").text(lang.lang_defaultemojis_text.replace("{{cat}}", defaultemojiname[target]));
$(".emoji-control").addClass("hide");
var announcement = false
if ($('#media').val() == 'announcement') {
announcement = true
}
var json = defaultemoji[target]
var emojis = ''
Object.keys(json).forEach(function(key) {
var emoji = json[key]
if (announcement) {
var def = `<a onclick="emojiReactionDef('${emoji['shortcode']}')" class="pointer">`
} else {
var def = `<a onclick="defEmoji('${emoji['shortcode']}')" class="pointer">`
}
emojis =
emojis +
`${def}
<span style="
width: 20px; height: 20px; display: inline-block; background-image: url('../../img/sheet.png'); background-size: 4900%;
background-position:${emoji['css']};"></span>
</a>`
})
$('#emoji-list').html(emojis)
$('#now-emoji').text(lang.lang_defaultemojis_text.replace('{{cat}}', defaultemojiname[target]))
$('.emoji-control').addClass('hide')
}
function customEmoji() {
$("#emoji-suggest").val("");
$(".emoji-control").removeClass("hide");
emojiList('home')
$('#emoji-suggest').val('')
$('.emoji-control').removeClass('hide')
emojiList('home')
}
function defEmoji(target) {
var selin = $("#textarea").prop('selectionStart');
if (!selin) {
selin = 0;
}
var emojiraw = newpack.filter(function (item, index) {
if (item.short_name == target) return true;
});
var hex = emojiraw[0].unified.split("-");
if (hex.length === 2) {
emoji = twemoji.convert.fromCodePoint(hex[0]) + twemoji.convert.fromCodePoint(hex[1]);
} else {
emoji = twemoji.convert.fromCodePoint(hex[0]);
}
var now = $("#textarea").val();
var before = now.substr(0, selin);
var after = now.substr(selin, now.length);
newt = before + emoji + after;
$("#textarea").val(newt);
$("#textarea").focus();
var selin = $('#textarea').prop('selectionStart')
if (!selin) {
selin = 0
}
var emojiraw = newpack.filter(function(item, index) {
if (item.short_name == target) return true
})
var hex = emojiraw[0].unified.split('-')
if (hex.length === 2) {
emoji = twemoji.convert.fromCodePoint(hex[0]) + twemoji.convert.fromCodePoint(hex[1])
} else {
emoji = twemoji.convert.fromCodePoint(hex[0])
}
var now = $('#textarea').val()
var before = now.substr(0, selin)
var after = now.substr(selin, now.length)
newt = before + emoji + after
$('#textarea').val(newt)
$('#textarea').focus()
}
function faicon() {
var json = faicons;
var emojis = "";
Object.keys(json).forEach(function (key) {
var emoji = json[key];
var eje = emoji.replace(/fa-/g, "");
emojis = emojis + '<a onclick="emojiInsert(\'[faicon]' + eje + '[/faicon]\')" class="pointer white-text" style="font-size:24px"><i class="fa ' + emoji + '"></i></a>';
});
$("#emoji-list").html(emojis);
$("#now-emoji").text("faicon");
$(".emoji-control").addClass("hide");
}
var json = faicons
var emojis = ''
Object.keys(json).forEach(function(key) {
var emoji = json[key]
var eje = emoji.replace(/fa-/g, '')
emojis =
emojis +
'<a onclick="emojiInsert(\'[faicon]' +
eje +
'[/faicon]\')" class="pointer white-text" style="font-size:24px"><i class="fa ' +
emoji +
'"></i></a>'
})
$('#emoji-list').html(emojis)
$('#now-emoji').text('faicon')
$('.emoji-control').addClass('hide')
}

View File

@ -193,7 +193,15 @@ function emojiGet(parse, started) {
function emojiList(target, reaction) {
$('#now-emoji').text(lang.lang_emoji_custom)
var acct_id = $('#post-acct-sel').val()
if (reaction && localStorage.getItem('emojiReaction_' + acct_id) != 'true') {
if(reaction && $('#media').val() == 'misskey') {
var misskeyReact = true
} else {
var misskeyReact = false
}
if (
misskeyReact &&
localStorage.getItem('emojiReaction_' + acct_id) != 'true'
) {
console.error('Disabled')
clear()
hide()
@ -263,9 +271,20 @@ function emojiList(target, reaction) {
var emoji = obj[i]
if (emoji) {
if (reaction) {
html =
html +
`<a onclick="emojiReaction(':${emoji.shortcode}:')" class="pointer"><img src="${emoji.url}" width="20" title="${emoji.shortcode}"></a>`
if (emoji.divider) {
html = html + '<p style="margin-bottom:0">' + emoji.cat + '</p>'
} else {
if (emoji.listed) {
if(misskeyReact) {
var shortcode = `:${emoji.shortcode}:`
} else {
var shortcode = emoji.shortcode
}
html =
html +
`<a onclick="emojiReaction('${shortcode}')" class="pointer"><img src="${emoji.url}" width="20" title="${emoji.shortcode}"></a>`
}
}
} else {
if (emoji.divider) {
html = html + '<p style="margin-bottom:0">' + emoji.cat + '</p>'

View File

@ -116,6 +116,7 @@ function reactiontoggle(id, acct_id, tlid) {
//reactioncustom
function reactioncustom(acct_id, id) {
$('#reply').val(id)
$('#media').val('misskey')
$('#unreact').hide()
$('#addreact').removeClass('hide')
$('#post-acct-sel').val(acct_id)
@ -186,9 +187,14 @@ function reactRefreshCore(json) {
}
}
function emojiReaction(emoji) {
var media = $('#media').val()
var acct_id = $('#post-acct-sel').val()
var id = $('#reply').val()
reaction(emoji, id, acct_id, null)
if(media == 'announcement') {
announReaction(id, acct_id, 0, false, emoji)
} else {
reaction(emoji, id, acct_id, null)
}
clear()
hide()
}

145
app/js/tl/announParse.js Normal file
View File

@ -0,0 +1,145 @@
function announParse(obj, acct_id, tlid) {
var template = ''
var datetype = localStorage.getItem('datetype')
var gif = localStorage.getItem('gif')
//Ticker
var tickerck = localStorage.getItem('ticker_ok')
if (tickerck == 'yes') {
var ticker = true
} else if (!ticker || ticker == 'no') {
var ticker = false
}
if (!datetype) {
datetype = 'absolute'
}
if (!gif) {
var gif = 'yes'
}
Object.keys(obj).forEach(function(key) {
var toot = obj[key]
var content = toot.content
if (toot.emojis) {
Object.keys(toot.emojis).forEach(function(key1) {
var emoji = toot.emojis[key1]
var shortcode = emoji.shortcode
if (gif == 'yes') {
var emoSource = emoji.url
} else {
var emoSource = emoji.static_url
}
var emoji_url = `
<img draggable="false" src="${emoSource}" class="emoji-img" data-emoji="${shortcode}"
alt=" :${shortcode}: " title="${shortcode}" onclick="this.classList.toggle('bigemoji');">
`
var regExp = new RegExp(':' + shortcode + ':', 'g')
content = content.replace(regExp, emoji_url)
})
}
content = twemoji.parse(content)
var reactions = ''
//既存のリアクション
if (toot.reactions) {
Object.keys(toot.reactions).forEach(function(key2) {
var reaction = toot.reactions[key2]
//普通の絵文字 or カスタム絵文字 は文字数判断。ただしスコットランド国旗みたいなやべぇやつに注意
var splitter = new GraphemeSplitter()
if (splitter.splitGraphemes(reaction.name).length > 1) {
//カスタム絵文字
var shortcode = reaction.shortcode
if (gif == 'yes') {
var emoSource = reaction.url
} else {
var emoSource = reaction.static_url
}
var emoji_url = `
<img draggable="false" src="${emoSource}" class="emoji-img" data-emoji="${shortcode}"
alt=" :${shortcode}: " title="${shortcode}">`
} else {
emoji_url = twemoji.parse(reaction.name)
}
var addClass = ''
if (reaction.me) {
addClass = 'reactioned'
}
reactions =
reactions +
`<div class="announReaction ${addClass}" onclick="announReaction('${toot.id}', '${acct_id}', '${tlid}', ${reaction.me},'${reaction.name}')">
${emoji_url} ${reaction.count}
</div>`
})
}
if (toot.ends_at) {
var ended = `<div class="announReaction" title="${date(poll.expires_at, 'absolute')}" style="width: auto; cursor: default;">
<i class="fas fa-arrow-right"></i>
${date(toot.ends_at, datetype)}
</div>`
} else {
var ended = ''
}
template =
template +
`<div class="announcement">
${content}
<div class="reactionsPack">
${reactions}
<div class="announReaction add" onclick="announReactionNew('${toot.id}', '${acct_id}', '${tlid}')"><i class="fas fa-plus"></i></div>
${ended}
</div>
</div>`
})
return template
}
function announReaction(id, acct_id, tlid, del, name) {
var at = localStorage.getItem('acct_' + acct_id + '_at')
var domain = localStorage.getItem('domain_' + acct_id)
var start = 'https://' + domain + '/api/v1/announcements/' + id + '/reactions/' + encodeURIComponent(name)
var httpreq = new XMLHttpRequest()
if(del) {
var method = 'DELETE'
} else {
var method = 'PUT'
}
httpreq.open(method, start, true)
httpreq.setRequestHeader('Content-Type', 'application/json')
httpreq.setRequestHeader('Authorization', 'Bearer ' + at)
httpreq.responseType = 'json'
httpreq.send()
httpreq.onreadystatechange = function() {
if (httpreq.readyState === 4) {
var json = httpreq.response
if (this.status !== 200) {
setLog(start, this.status, this.response)
}
announ(acct_id, tlid)
}
}
}
function announReactionNew(id, acct_id, tlid) {
$('#reply').val(id)
$('#media').val('announcement')
$('#unreact').hide()
$('#addreact').removeClass('hide')
$('#post-acct-sel').val(acct_id)
$('select').formSelect()
localStorage.setItem('nohide', true)
show()
emojiToggle(true)
$('#left-side').hide()
}
function emojiReactionDef(target) {
var emojiraw = newpack.filter(function(item, index) {
if (item.short_name == target) return true
})
var hex = emojiraw[0].unified.split('-')
if (hex.length === 2) {
emoji = twemoji.convert.fromCodePoint(hex[0]) + twemoji.convert.fromCodePoint(hex[1])
} else {
emoji = twemoji.convert.fromCodePoint(hex[0])
}
var acct_id = $('#post-acct-sel').val()
var id = $('#reply').val()
announReaction(id, acct_id, 0, false, emoji)
clear()
hide()
}

View File

@ -880,7 +880,7 @@ function misskeyUserparse(obj, auth, acct_id, tlid, popup) {
}
var ftxt = lang.lang_parse_followed;
if (popup > 0 || popup == -1) {
var notftext = '<span class="cbadge"title="' + date(toot.createdAt,
var notftext = '<span class="cbadge" title="' + date(toot.createdAt,
'absolute') + '(' + lang.lang_parse_notftime + ')"><i class="far fa-clock"></i>' + date(toot.createdAt,
datetype) +
'</span>' + ftxt + '<br>';

View File

@ -64,6 +64,9 @@ function tl(type, data, acct_id, tlid, delc, voice, mode) {
)
$('#notice_icon_' + tlid).text('bookmark')
return
} else if (type == 'home') {
//ホームならお知らせ「も」取りに行く
announ(acct_id, tlid);
}
localStorage.setItem('now', type)
todo(cap(type) + ' TL Loading...')
@ -311,6 +314,8 @@ function reload(type, cc, acct_id, tlid, data, mute, delc, voice, mode) {
}
} else if (typeA == 'filters_changed') {
filterUpdate(acct_id)
} else if (~typeA.indexOf('announcement')) {
announ(acct_id, tlid)
}
}
}
@ -1167,3 +1172,33 @@ function getBookmark(acct_id, tlid, more) {
}
}
}
//Announcement
function announ(acct_id, tlid) {
var at = localStorage.getItem('acct_' + acct_id + '_at')
var domain = localStorage.getItem('domain_' + acct_id)
var start = 'https://' + domain + '/api/v1/announcements'
var httpreq = new XMLHttpRequest()
httpreq.open('GET', start, true)
httpreq.setRequestHeader('Content-Type', 'application/json')
httpreq.setRequestHeader('Authorization', 'Bearer ' + at)
httpreq.responseType = 'json'
httpreq.send()
httpreq.onreadystatechange = function() {
if (httpreq.readyState === 4) {
var json = httpreq.response
if (this.status !== 200) {
setLog(start, this.status, this.response)
}
if (json.length > 0) {
$('.notf-announ_' + acct_id).removeClass('hide')
$('.notf-announ_' + acct_id + '_ct').text(json.length)
} else {
$('.notf-announ_' + acct_id).addClass('hide')
}
var templete = announParse(json, acct_id, tlid)
$('#announce_' + tlid).html(templete)
jQuery('time.timeago').timeago()
todc()
}
}
}

View File

@ -234,7 +234,7 @@ function parseColumn(target, dontclose) {
var unread = `<a id="unread_${key}" onclick="showUnread('${key}','${acct.type}','${acct.domain}')"
class="setting nex" title="${lang.lang_layout_unread}">
<i class="material-icons waves-effect nex">more</i>
</a>`
</a>${lang.lang_layout_unread}<br>`
var notfDomain = acct.domain
var notfKey = key
var if_tag = ''
@ -368,7 +368,10 @@ function parseColumn(target, dontclose) {
title="${unique_notf}" ${icnsert}>
<i class="material-icons waves-effect nex notf-icon_${acct.domain}">notifications</i>
</a>
${unread}
<span class="cbadge hide notf-announ_${acct.domain}" style="margin-right:0" onclick="notfToggle('${acct.domain}','${key}')">
<i class="fas fa-bullhorn"></i>
<span class="notf-announ_${acct.domain}_ct">0</span>
</span>
${if_tag_btn}
</div>
<div class="area-sta">
@ -389,10 +392,12 @@ function parseColumn(target, dontclose) {
</div>
</div>
<div class="column-hide notf-indv-box z-depth-4" id="notf-box_${notfKey}">
<div id="announce_${notfKey}" style="border: 1px solid"></div>
<div id="notifications_${notfKey}" data-notf="${notfDomain}" data-type="notf" class="notf-timeline">
</div>
</div>
<div class="column-hide notf-indv-box" id="util-box_${key}" style="padding:5px;">
${unread}
${exclude}${left_hold}
<a onclick="mediaToggle('${key}')" class="setting nex">
<i class="material-icons waves-effect nex" title="${lang.lang_layout_mediafil}">perm_media</i>

View File

@ -1226,6 +1226,7 @@
<script type="text/javascript" src="../../js/tl/misskeyparse.js"></script>
<script type="text/javascript" src="../../js/tl/dm.js"></script>
<script type="text/javascript" src="../../js/ui/scroll.js"></script>
<script type="text/javascript" src="../../js/tl/announParse.js"></script>
<script type="text/javascript" src="../../js/tl/tl.js"></script>
<script type="text/javascript" src="../../js/tl/card.js"></script>
<script type="text/javascript" src="../../js/tl/parse.js"></script>