mirror of
https://github.com/twisterarmy/twister-html.git
synced 2025-02-09 05:24:20 +00:00
commit
43d3169047
@ -28,6 +28,7 @@
|
||||
<script src="js/interface_common.js"></script>
|
||||
<script src="js/interface_home.js"></script>
|
||||
<script src="js/jquery.textcomplete.min.js"></script>
|
||||
<script src="js/twister-crypto-bundle.js"></script>
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/twister_mini.png" />
|
||||
</head>
|
||||
|
@ -672,17 +672,10 @@ function openMentionsModalHandler(peerAlias) {
|
||||
});
|
||||
|
||||
var req = queryStart(modal.content.find('.postboard-posts'), peerAlias, 'mention');
|
||||
modal.content.find('.postboard-news')
|
||||
.on('click',
|
||||
{req: req, cbFunc: (peerAlias === defaultScreenName) ? resetMentionsCount : ''},
|
||||
handleClickDisplayPendingTwists
|
||||
)
|
||||
;
|
||||
modal.content.find('.postboard-news').on('click', {req: req}, handleClickDisplayPendingTwists);
|
||||
|
||||
if (peerAlias === defaultScreenName) {
|
||||
if (peerAlias === defaultScreenName)
|
||||
modal.content.on('scroll', handleMentionsModalScroll);
|
||||
resetMentionsCount();
|
||||
}
|
||||
}
|
||||
|
||||
function openFollowersModal(peerAlias) {
|
||||
@ -943,9 +936,9 @@ function addToCommonDMsList(list, targetAlias, message) {
|
||||
getFullname(targetAlias, item.find('a.post-info-name'));
|
||||
}
|
||||
|
||||
if (_newDMsPerUser[targetAlias] > 0)
|
||||
if (twister.DMs[targetAlias].lengthNew > 0)
|
||||
item.addClass('new')
|
||||
.find('.messages-qtd').text(_newDMsPerUser[targetAlias]).show();
|
||||
.find('.messages-qtd').text(twister.DMs[targetAlias].lengthNew).show();
|
||||
|
||||
var items = list.children();
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
// uses Polyglot.js ( https://github.com/airbnb/polyglot.js ) to translate interface
|
||||
|
||||
// translators: add your language code here such as "es" for Spanish, "ru" for Russian
|
||||
var knownLanguages = ["en","es","nl","it","fr","ru","de","zh-CN","ja","pt-BR","tr","uk","cs"];
|
||||
var knownLanguages = ["en","es","nl","it","fr","ru","de","zh-CN","ja","pt-BR","tr","uk","cs","cmn","yue"];
|
||||
|
||||
if ($.Options.locLang.val === 'auto') {
|
||||
// detect language with JavaScript
|
||||
@ -367,7 +367,8 @@ if(preferredLanguage == "en"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Terminate Daemon": "Terminate Daemon",
|
||||
"New post": "New post",
|
||||
"Search": "Search",
|
||||
@ -736,7 +737,8 @@ if(preferredLanguage == "es"){
|
||||
"Language": "Idioma",
|
||||
"Sound": "Sonido",
|
||||
"Users": "Usuarios",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -1099,7 +1101,8 @@ if(preferredLanguage == "uk"){
|
||||
"Language": "Мова",
|
||||
"Sound": "Звук",
|
||||
"Users": "Користувачі",
|
||||
"Direct Message's copy to self": "Повідомлення скопійовано самому собі",
|
||||
'dm_copy_outgoing_to_self': 'Повідомлення скопійовано самому собі',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Статистика трафіку",
|
||||
"Direct messages with": "Співбесіда з",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
@ -1465,7 +1468,8 @@ if(preferredLanguage == "zh-CN"){
|
||||
"Language": "语言",
|
||||
"Sound": "声音",
|
||||
"Users": "用户",
|
||||
"Direct Message's copy to self": "将私信发一份副本给我",
|
||||
'dm_copy_outgoing_to_self': '将私信发一份副本给我',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Terminate Daemon": "终止后台进程",
|
||||
"New post": "新推文",
|
||||
"Search": "搜索",
|
||||
@ -1835,7 +1839,8 @@ if(preferredLanguage == "nl"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -2199,7 +2204,8 @@ if(preferredLanguage == "it"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -2565,7 +2571,8 @@ if(preferredLanguage == "fr"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -2932,7 +2939,8 @@ if(preferredLanguage == "ru"){
|
||||
"Language": "Язык",
|
||||
"Sound": "Звук",
|
||||
"Users": "Пользователи",
|
||||
"Direct Message's copy to self": "Синхронизировать отправленные личные сообщения",
|
||||
'dm_copy_outgoing_to_self': 'Синхронизировать отправленные личные сообщения',
|
||||
'dm_encrypt_local_cache': 'Шифровать локальный кэш данных',
|
||||
"Terminate Daemon": "Выключить twister демон",
|
||||
"New post": "Новый пост",
|
||||
"Search": "Поиск",
|
||||
@ -3304,7 +3312,8 @@ if(preferredLanguage == "de"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Kopie der Direktnachricht an mich selbst",
|
||||
'dm_copy_outgoing_to_self': 'Kopie der Direktnachricht an mich selbst',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -3667,7 +3676,8 @@ if(preferredLanguage == "ja"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -4035,7 +4045,8 @@ if(preferredLanguage == "pt-BR"){
|
||||
"Language": "Language",
|
||||
"Sound": "Sound",
|
||||
"Users": "Users",
|
||||
"Direct Message's copy to self": "Direct Message's copy to self",
|
||||
'dm_copy_outgoing_to_self': 'Copy outgoing messages to self',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Traffic information",
|
||||
"DHT Torrents:": "DHT Torrents:",
|
||||
"Peers:": "Peers:",
|
||||
@ -4400,7 +4411,8 @@ if(preferredLanguage == "tr"){
|
||||
"Language": "Dil",
|
||||
"Sound": "Ses",
|
||||
"Users": "Kullanıcılar",
|
||||
"Direct Message's copy to self": "Özel iletinin kopyasını sakla",
|
||||
'dm_copy_outgoing_to_self': 'Özel iletinin kopyasını sakla',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"Traffic information": "Trafik bilgileri",
|
||||
"DHT Torrents:": "DHT Torrentleri:",
|
||||
"Peers:": "Eşler:",
|
||||
@ -4765,7 +4777,8 @@ if(preferredLanguage == "cs"){
|
||||
"Language": "Jazyk",
|
||||
"Sound": "Zvuky",
|
||||
"Users": "Uživatelé",
|
||||
"Direct Message's copy to self": "Posílat kopie přímých zpráv sám sobě",
|
||||
'dm_copy_outgoing_to_self': 'Posílat kopie přímých zpráv sám sobě',
|
||||
'dm_encrypt_local_cache': 'Encrypt local data cache',
|
||||
"New post": "Nový příspěvek",
|
||||
"Search": "Hledat",
|
||||
"Direct Msg": "Přímá zpráva",
|
||||
@ -4793,6 +4806,764 @@ if(preferredLanguage == "cs"){
|
||||
};
|
||||
}
|
||||
|
||||
if(preferredLanguage == "cmn"){
|
||||
polyglot.locale("cmn");
|
||||
wordset = {
|
||||
"Maximum post size to show": "可顯示的最長推文",
|
||||
"Maximum post size to send": "可發送的最長推文",
|
||||
"characters": "字元",
|
||||
"WebTorrent": "網頁訊流",
|
||||
"WebTorrent support to display shortened URL media": "網頁訊流支援顯示短版網址媒體",
|
||||
"External IP:": "外部網路位址:",
|
||||
"External Port 1 (TCP):": "外部通訊埠一(TCP):",
|
||||
"External Port 2 (TCP+UDP):": "外部通訊埠二(TCP+UDP):",
|
||||
"Test open port (external site)": "測試打開的通訊埠(外部站臺)",
|
||||
"Actions ▼": "動作 ▼",
|
||||
"Active DHT nodes:": "分散式雜湊表活躍節點:",
|
||||
"Add DNS": "加入 DNS",
|
||||
"Add peer": "加入對等點",
|
||||
"ajax_error": "Ajax 錯誤:%{error}", // JavaScript error
|
||||
"All users publicly followed by": "所有使用者被公開跟隨自",
|
||||
"Available": "可用", // username is available
|
||||
"Appearance": "外觀",
|
||||
"Apply": "套用",
|
||||
"Block chain information": "區塊鏈資訊",
|
||||
"Block chain is up-to-date, twister is ready to use!": "區塊鏈已更新,Twister 備妥待用!",
|
||||
"Block generation": "區塊生成:",
|
||||
"busted_oh": "噢,不!",
|
||||
"busted_avowal": "檢測到有人嘗試注入惡意材料",
|
||||
"btn_ok": "沒問題",
|
||||
"Cancel": "取消",
|
||||
'cant_get_requested_resourse': "無法於 %{link} 取得資源\n 狀態:%{status}。",
|
||||
"clear_cache": "清空快取",
|
||||
"Confirm": "確認",
|
||||
"сonfirm_group_leaving_header": "確認要離開群組",
|
||||
"сonfirm_group_leaving_body": "確定要離開 %{alias} 群組?",
|
||||
"confirm_switch_to_network":
|
||||
"本地守護程式還未連線到網路,或者區塊鏈已經過期。\n" +
|
||||
"如果您待在這個頁面,您的動作可能沒有效用。\n" +
|
||||
"您要檢查 [網路] 狀態頁面(%{page}) 做為替代嗎?",
|
||||
"confirm_terminate_daemon": "確定要退離守護程式?\nTwister 客戶端將停止作用。",
|
||||
"confirm_unfollow_@": "確定要取消跟隨 @%{alias}?",
|
||||
"confirm_uri_shortener_clear_cache": "確定要清空瀏覽器的短版網址快取?",
|
||||
"Change user": "變更使用者",
|
||||
"Checking...": "檢查…", // checking if username is available
|
||||
"Collapse": "塌縮", // smaller view of a post
|
||||
"Configure block generation": "組配區塊生成",
|
||||
"Connections:": "連接:", // to network
|
||||
"Connection lost.": "連線已經中斷。",
|
||||
"daemon_is_obsolete": "Twister 守護程式已過時,必須使用 %{versionReq} 或更高版本",
|
||||
"days": "%{smart_count} 天",
|
||||
"Detailed information": "詳細資訊",
|
||||
"DHT network down.": "分散式雜湊表 網路斷線。",
|
||||
"Direct Messages": "私人訊息",
|
||||
"Group Messages": "群組訊息",
|
||||
"Group Messages — New Group Creation": "群組訊息 — 新群組建立",
|
||||
"Group Messages — Join Group": "群組訊息 — 參與群組",
|
||||
"group_key_cant_import": "無法匯入私人訊息的群組金鑰",
|
||||
"group_key_is_invalid_perhaps": "也許金鑰無效",
|
||||
"group_key_was_imported": "已匯入私人訊息群組 %{alias} 的金鑰。\n"
|
||||
+"很快就能擷取到它的訊息。",
|
||||
"direct_messages_with": "與 %{username} 的私人訊息",
|
||||
"Disable": "停用",
|
||||
"display_mentions": "顯示提及次數",
|
||||
"Display retransmissions": "顯示轉推次數",
|
||||
"DNS to obtain list of peers:": "用來取得對等點列表的 DNS:",
|
||||
"do_not_show_it_again": "再也不要顯示它",
|
||||
"downloading_block_chain": "正在下載區塊鏈,繼續之前請稍待 (區塊鏈仍落後 %{days} 天)。",
|
||||
"download_posts_status": "已下載 %{portion} 則推文", // Downloaded 10/30 posts
|
||||
"Enable": "啟用",
|
||||
"error": "錯誤:%{error}",
|
||||
"error_connecting_to_daemon": "連線到本地 Twister 守護程式時發生錯誤。",
|
||||
"Error in 'createwalletuser' RPC.": "在 createwalletuser RPC 時發生錯誤。",
|
||||
"Error in 'importprivkey'": "在 importprivkey RPC 時發生錯誤:%{rpc}",
|
||||
"Error in 'sendnewusertransaction' RPC.": "在 sendnewusertransaction RPC 時發生錯誤。",
|
||||
"Expand": "展開", // larger view of a post
|
||||
"Favorite": "收藏",
|
||||
"File APIs not supported in this browser.": "這個瀏覽器不支援檔案應用程式介面。",
|
||||
"Follow": "跟隨",
|
||||
"Following config": "跟隨組配",
|
||||
"select_way_to_follow_@": "您想以哪種方式跟隨 @%{alias}",
|
||||
"Followed by": "跟隨者",
|
||||
"followed_by": "被 %{username} 跟隨",
|
||||
"Followers": "跟隨者",
|
||||
"Followers_of": "@%{alias} 的跟隨者",
|
||||
"Following": "跟隨中",
|
||||
"Following users": "跟隨的使用者",
|
||||
"Force connection to peer:": "強制連接到對等點:",
|
||||
"General information": "一般資訊",
|
||||
"Generate blocks (send promoted messages)": "產生區塊 (發送推廣訊息)",
|
||||
"Home": "首頁", // homepage
|
||||
"hours": "%{smart_count} 小時",
|
||||
"Internal error: lastPostId unknown (following yourself may fix!)": "內部錯誤:lastPostId 不明 (跟隨您自己也許就能修正!)",
|
||||
"Known peers:": "已知對等點:",
|
||||
"Last block is ahead of your computer time, check your clock.": "最後一段區塊已經超前了您的電腦時間,請檢查您的系統時鐘。",
|
||||
"mentions_at": "提及 @%{user}",
|
||||
"minutes": "%{smart_count} 分鐘",
|
||||
"Must be 16 characters or less.": "必須是 16 個字元或更少。", // username
|
||||
"Network": "網路",
|
||||
"Network config": "網路組配",
|
||||
"Network status": "網路狀態",
|
||||
"New direct message...": "新的私人訊息…",
|
||||
"New Post...": "新推文…",
|
||||
"New group": "新群組",
|
||||
"Group description": "群組描述",
|
||||
"Peers to invite": "可邀請的對等點",
|
||||
"Join group": "參與群組",
|
||||
"Select group(s)": "選取群組",
|
||||
"Create": "建立",
|
||||
"Join": "參與",
|
||||
"Invite": "邀請",
|
||||
"Invite peers": "邀請對等點",
|
||||
"Leave group": "離開群組",
|
||||
"You got": "您得到",
|
||||
"in postboard": "於推布欄",
|
||||
"in search result": "於搜尋結果",
|
||||
"in top trends": "於熱門趨勢",
|
||||
"new_posts": "%{smart_count} 則新推文",
|
||||
"new_mentions": "%{smart_count} 次新提及",
|
||||
"new_direct_messages": "%{smart_count} 則新的私人訊息",
|
||||
"new_group_messages": "%{smart_count} 則新的群組訊息",
|
||||
"nobody": "沒有人", // used to promote a post without attaching the user
|
||||
"Not available": "無名可用", // username is not available
|
||||
"warn_following_not_any": "沒有跟隨任何推友!\n請搜尋並跟隨某人。",
|
||||
"warn_followers_not_all": "好吧,目前還沒有容易的方式,可以知道所有跟隨您的人。\n"
|
||||
+"計數器衹有指示已知的對等點數量,他們正在共享您的推文訊流。\n"
|
||||
+"以下列表包含的推友,大多是您所跟隨的人。",
|
||||
"warn_followers_not_all_of": "好吧,目前還沒有容易的方式,可以知道某人的所有跟隨者。\n"
|
||||
+"以下列表衹包括幾個,或許是公開跟隨 @%{alias} 的人。",
|
||||
"notify_desktop_error": "Twister 無法進行桌面通知:發生不明錯誤。",
|
||||
"notify_desktop_perm_denied": "Twister 無法進行桌面通知:權限被拒。\n\n如果您要獲得通知,請在您的瀏覽器設定值中,允許它們用於 %{this_domain}。",
|
||||
"notify_desktop_test": "所有人都在推文。\n歡迎您的加入。",
|
||||
"notify_desktop_title": "注意,這裡是 Twister!",
|
||||
"post_preview_dummy": '這裡有 *粗體*、~斜體~、-刪除線- 以及 _加底線_ 的文字。\n'
|
||||
+ '同樣但是例外排除的:`*粗體*、~斜體~、-刪除線- 以及 _加底線_`。\n'
|
||||
+ '鏈結到 [最棒的圖標](%{logo}) 以及我們華麗的站臺:%{site}。',
|
||||
"Number of blocks in block chain:": "區塊鏈中的區塊數量:",
|
||||
"Number of CPUs to use": "使用的中央處理器數量:",
|
||||
"Only alphanumeric and underscore allowed.": "衹允許文數字與底線。",
|
||||
"peer address": "對等點位址",
|
||||
"Private": "私人的",
|
||||
"Profile": "側寫",
|
||||
"Postboard": "推布欄",
|
||||
"post": "推文", // verb - button to post a message
|
||||
"Post to promote:": "用來推廣的推文:",
|
||||
"Posts": "推文",
|
||||
"propagating_nickname": "將暱稱 %{username} 傳播到網路…",
|
||||
"Public": "公開",
|
||||
"Refresh": "重新整理",
|
||||
"retransmit_this": "轉發這則推文給您的跟隨者?",
|
||||
"Reply": "回覆",
|
||||
"Reply...": "回覆…",
|
||||
"reply_to": "回覆給 %{fullname}",
|
||||
"Retransmit": "轉發",
|
||||
"Retransmits": "轉發",
|
||||
"Retransmitted by": "轉發自",
|
||||
"Switch to Reply": "切換為回覆",
|
||||
"Switch to Retransmit": "切換為轉發",
|
||||
"search": "搜尋",
|
||||
"seconds": "%{smart_count} 秒",
|
||||
"send": "發送",
|
||||
"Send post with username": "發送推文所用的使用者名稱:",
|
||||
"send_DM": "發送私人訊息",
|
||||
"Sent Post to @": "已發送推文給 @",
|
||||
"Setup account": "設定帳號",
|
||||
"shorten_URI": "短版網址",
|
||||
"shorten_URI_enter_link": "輸入長版網址鏈結。\n"
|
||||
+"註記:短版網址將為您產生空的推文以包含完整網址。\n"
|
||||
+"這一則特殊推文不會顯示於 Twister 客戶端,但是您的推文計數將會增加。",
|
||||
"shorten_URI_its_public_is_it_ok": "您的鏈結將是公開可讀的!確定這樣可以嗎?",
|
||||
"URI_shortener": "網址縮短器",
|
||||
"The File APIs are not fully supported in this browser.": "這個瀏覽器並不完全支援檔案應用軟體介面。",
|
||||
"time_ago": "%{time} 之前", // 5 minutes ago
|
||||
"Time of the last block:": "最後一段區塊的時間:",
|
||||
"Type message here": "在這裡輸入訊息",
|
||||
"Unfollow": "取消跟隨",
|
||||
"Update": "更新",
|
||||
"Auto updating": "自動更新",
|
||||
'updates_are_available': '有可用更新',
|
||||
'updates_not_available': '沒有可用更新',
|
||||
'updates_check_client': '檢查有無客戶端軟體更新',
|
||||
'updates_repo_overview': '目前我們是基於 %{repo} 分支 %{branch} 上於\n %{date} 的定案 %{commit}\n'
|
||||
+'但是原始碼的最前緣已經位於\n 定案 %{commitUpstream} 的 %{dateUpstream}。',
|
||||
'updates_checkout_diff': '簽出 [GitHub 上的差異](%{link}) 來瞭解變更了什麼。',
|
||||
'updates_checkout_diff_nfmt': '簽出 GitHub 上的差異來瞭解變更了什麼:\n %{link}',
|
||||
'updates_upstream_isnt_changed': '相應分支的原始碼儲存庫似乎沒有變更。',
|
||||
"Updating status...": "更新狀態…", // status of block chain
|
||||
'new_account_briefing': '正在將新建立的帳號傳播到網路中。'
|
||||
+'請不要關閉這個視窗,也許需要幾分鐘。\n\n'
|
||||
+'您的密鑰是:*%{secretKey}*\n\n'
|
||||
+'強烈建議您利用這段時間去儲存您的密鑰。'
|
||||
+'印出來、做螢幕快照、使用您手機中的照相功能,或是將它寫在紙上。\n\n'
|
||||
+'從不同的電腦使用這個帳號時將會需要密鑰。'
|
||||
+'如果您一旦遺失密鑰,您的帳號將永遠被鎖住'
|
||||
+'(註記:~這是開發中軟體,它也許會崩潰而造成資料漏失~)。\n\n'
|
||||
+'請稍待。當您還沒唸完 ~decentralization~ 之前,就會顯示「確定」按鈕。',
|
||||
"user_not_yet_accepted": "其他對等點尚未接受這位新使用者。\n"+
|
||||
"很不幸地,無法儲存側寫\n"+
|
||||
"或在這個狀態下發送任何推文。\n\n"+
|
||||
"請稍待幾分鐘再繼續。\n\n"+
|
||||
"「儲存變更」將在處理完成時\n"+
|
||||
"自動啟用。(我保證這是您\n"+
|
||||
"使用 Twister 之前的最後一次\n"+
|
||||
"等待)。\n\n"+
|
||||
"祕訣:趁這時選擇您的頭像!",
|
||||
"users_mentions": "@%{username} 的提及次數",
|
||||
"users_profile": "%{username} 的側寫",
|
||||
"username_undefined": "未定義的使用者名稱,這是登入必要項目。",
|
||||
"View": "檢視",
|
||||
"View All": "檢視全部",
|
||||
"Who to Follow": "可以跟隨誰",
|
||||
"Your message was sent!": "您的訊息已發送!",
|
||||
"twister login": "Twister 登入",
|
||||
"Existing local users": "既有本地使用者",
|
||||
"Or...": "或…",
|
||||
"Create a new user": "建立新使用者",
|
||||
"Login": "登入",
|
||||
"Check availability": "檢查可用程度",
|
||||
"Create this nickname": "建立這個暱稱",
|
||||
"Type nickname here": "在這裡輸入暱稱",
|
||||
"Import secret key": "匯入密鑰",
|
||||
"52-characters secret": "52 個字元的密鑰",
|
||||
"With nickname": "與暱稱",
|
||||
"Import key": "匯入金鑰",
|
||||
"Client Version:": "客戶端版本:",
|
||||
"Mining difficulty:": "挖礦難度:",
|
||||
"Block generation status": "區塊生成狀態",
|
||||
"Current hash rate:": "目前雜湊比率:",
|
||||
"Terminate Daemon:": "終止守護程式:",
|
||||
"Exit": "退離",
|
||||
"Save Changes": "儲存變更",
|
||||
"profile_saved": "側寫資料已被儲存到分散式雜湊表。",
|
||||
"profile_not_saved": "無法儲存側寫資料。",
|
||||
"Secret key:": "密鑰:",
|
||||
"You have to log in to post messages.": "您必須登入才能推送訊息。",
|
||||
"You have to log in to post replies.": "您必須登入才能回覆訊息。",
|
||||
"You have to log in to retransmit messages.": "您必須登入才能轉發訊息。",
|
||||
"You have to log in to use direct messages.": "您必須登入才能使用私人訊息。",
|
||||
"You have to log in to follow users.": "您必須登入才能跟隨使用者。",
|
||||
"You are not following anyone because you are not logged in.": "您沒有跟隨任何人因為您還未登入。",
|
||||
"You don't have any followers because you are not logged in.": "您沒有任何跟隨者因為您還未登入。",
|
||||
"No one can mention you because you are not logged in.": "沒有人可以提及您因為您還未登入。",
|
||||
"You don't have any profile because you are not logged in.": "您沒有任何側寫因為您還未登入。",
|
||||
"Options": "選項",
|
||||
"Switch to Promoted posts": "切換至推廣推文",
|
||||
"Switch to Normal posts": "切換至一般推文",
|
||||
"Use language": "使用語言",
|
||||
"Ignore": "忽略",
|
||||
"Ignore and clear out": "忽略並清空",
|
||||
"Theme": "布景主題",
|
||||
"Keys": "金鑰",
|
||||
"Notifications": "通知",
|
||||
"Desktop notifications": "桌面通知",
|
||||
"Sound notifications": "聲音通知",
|
||||
"Volume": "音量",
|
||||
"Test": "測試",
|
||||
"Send key": "發送金鑰",
|
||||
"Posts display": "推文顯示",
|
||||
"Post editor": "推文編輯器",
|
||||
"Post preview": "推文預覽",
|
||||
"Inline image preview": "內聯影像預覽",
|
||||
"Display": "顯示",
|
||||
"Line feeds": "送列符號",
|
||||
"Markout": "註明標記",
|
||||
"Supported punctuations:": "支援的標點符號:",
|
||||
"Supported emotions:": "支援的表情符號:",
|
||||
"Supported signs:": "支援的符號:",
|
||||
"Supported fractions:": "支援的分數:",
|
||||
"Automatic unicode conversion options": "萬國碼自動轉換選項",
|
||||
"Convert punctuations to unicode": "轉換標點符號為萬國碼",
|
||||
"Convert emotions codes to unicode symbols": "轉換表情符號編碼為萬國碼符號",
|
||||
"Convert common signs to unicode": "轉換一般符號為萬國碼",
|
||||
"Convert fractions to unicode": "轉換分數為萬國碼",
|
||||
"Convert all": "轉換全部",
|
||||
"Auto": "自動",
|
||||
"Original": "原版",
|
||||
"none": "無",
|
||||
"Custom": "自訂",
|
||||
"Mentions": "提及",
|
||||
"Use proxy for image preview only": "代理伺服器衹用於影像預覽",
|
||||
"Use external links behind a proxy": "使用代理伺服器後方的外部鏈結",
|
||||
"There aren't any posts with this hashtag.": "沒有任何推文包含這個雜湊標籤。",
|
||||
"Split only new post": "衹分割新的推文",
|
||||
"Split all": "分割全部",
|
||||
"Don't split": "不要分割",
|
||||
"Split long posts": "分割長的推文",
|
||||
"Posts that begin with mention": "以提及做為開頭的推文",
|
||||
"Show all": "全部顯示",
|
||||
"Show only if I am in": "衹顯示有我的推文",
|
||||
"Show if it's between users I follow": "如果是我跟隨的使用者才顯示",
|
||||
"Postboard displays": "推布欄顯示",
|
||||
"RTs those are close to original twist": "與原始推文相近的轉推",
|
||||
"Show if the original is older than": "衹顯示原始推文出現超過",
|
||||
"hour(s)": "小時",
|
||||
"second(s)": "秒",
|
||||
"only positive numbers!": "衹允許正數!",
|
||||
"Language filtering": "語言篩選",
|
||||
"By blacklist": "依照黑名單",
|
||||
"By whitelist": "依照白名單",
|
||||
"Comma separated ISO 639-3 language codes": "逗號分隔的 ISO 639-3 語言編碼",
|
||||
"Accuracy": "準確度",
|
||||
"Simulation mode": "模擬模式",
|
||||
"This post is treated by language filter": "這則推文由語言篩選器所 %{treated}。",
|
||||
"blocked": "阻斷",
|
||||
"passed": "傳遞",
|
||||
"not analyzed": "無法分析",
|
||||
"Reason: this": "原因:%{this}",
|
||||
"this doesnt contain that": "%{this} 不包含 %{that}",
|
||||
"this is undefined": "%{this} 未定義",
|
||||
"blacklist": "黑名單",
|
||||
"whitelist": "白名單",
|
||||
"language of this": "語言所屬",
|
||||
"its undefined language": "它是種未定義的語言",
|
||||
"its this, blacklisted": "它是 %{this},已列入黑名單",
|
||||
"its this, whitelisted": "它是 %{this},已列入白名單",
|
||||
"Most possible language: this": "最可能的語言:%{this}",
|
||||
"Scope of usage": "使用的範圍",
|
||||
"Show with every user name": "每位使用者都要顯示",
|
||||
"Show at profile modal only": "衹有側寫頁面才要顯示",
|
||||
"Show if a user follows me": "跟隨我的使用者才顯示",
|
||||
"follows you": "跟隨您",
|
||||
"Show conversation": "顯示會話",
|
||||
"Mark all as read": "標記所有為已讀",
|
||||
"show_more_count": "%{smart_count} 更多…",
|
||||
"hide": "隱藏",
|
||||
"Show more in this conversation...": "顯示更多會話內容…",
|
||||
"conversation_title": "@%{username} 的會話",
|
||||
"copy_to_clipboard": "按下 Ctrl/Cmd+C 來拷貝,然後按下 Enter 來關閉",
|
||||
"Normal posts": "一般推文",
|
||||
"Promoted posts": "推廣推文",
|
||||
"Messages": "訊息",
|
||||
"Edit profile": "編輯側寫",
|
||||
"Top Trends": "熱門趨勢",
|
||||
"Twistday Reminder": "開推周年紀念日提醒訊息",
|
||||
"Show upcoming in near future": "顯示不久即將迎來慶祝的人",
|
||||
"Who's celebrating Twistday": "誰正在慶祝開推周年紀念日",
|
||||
"Today's luckies:": "今天的幸運兒:",
|
||||
"Upcoming ones:": "即將迎來慶祝的人:",
|
||||
"post_rt_sign_prep": "再次推文自",
|
||||
"post_rt_time_prep": "於",
|
||||
"undo": "復原",
|
||||
"Daemon exited...": "已退離守護程式…",
|
||||
"Secret Key": "密鑰",
|
||||
"Copy to clipboard": "拷貝到剪貼簿",
|
||||
"Full name here": "全名",
|
||||
"Describe yourself": "描述您自己",
|
||||
"Location": "位置",
|
||||
"website": "網站",
|
||||
"Tox address": "Tox 位址",
|
||||
"Bitmessage address": "Bitmessage 位址",
|
||||
"Language": "語言",
|
||||
"Sound": "聲音",
|
||||
"Users": "使用者",
|
||||
"Direct Message's copy to self": "私人訊息拷貝給自己",
|
||||
"Terminate Daemon": "終止守護程式",
|
||||
"New post": "新推文",
|
||||
"Search": "搜尋",
|
||||
"Direct Msg": "私人訊息",
|
||||
"Traffic information": "流量資訊",
|
||||
"DHT Torrents:": "分散式雜湊表訊流:",
|
||||
"Peers:": "對等點:",
|
||||
"Peer List Size:": "對等點列表大小:",
|
||||
"Active Requests:": "活躍請求:",
|
||||
"Download:": "下載:",
|
||||
"Upload:": "上傳:",
|
||||
"DHT Download:": "分散式雜湊表下載:",
|
||||
"DHT Upload:": "分散式雜湊表上傳:",
|
||||
"IP Overhead Download:": "網際網路協定耗費下載:",
|
||||
"IP Overhead Upload:": "網際網路協定耗費上傳:",
|
||||
"Payload Download:": "酬載下載:",
|
||||
"Payload Upload:": "酬載上傳:",
|
||||
"No favs here because you are not logged in.": "因為您還沒登入,這裡不會顯示收藏。",
|
||||
"users_favs": "@%{username} 的收藏",
|
||||
"Favorites": "收藏",
|
||||
"You have to log in to favorite messages.": "您必須登入以收藏訊息。",
|
||||
"fav_this": "它為您所獨有?",
|
||||
"Last activity": "最近一次活動",
|
||||
"New Users": "新近使用者",
|
||||
"Live tracking" : "即時追蹤"
|
||||
};
|
||||
}
|
||||
|
||||
if(preferredLanguage == "yue"){
|
||||
polyglot.locale("yue");
|
||||
wordset = {
|
||||
"Maximum post size to show": "可顯示其至長推文",
|
||||
"Maximum post size to send": "可寄個其至長推文",
|
||||
"characters": "字符",
|
||||
"WebTorrent": "網頁訊流",
|
||||
"WebTorrent support to display shortened URL media": "網頁訊流支援顯示短版網址媒體",
|
||||
"External IP:": "外部網絡位址:",
|
||||
"External Port 1 (TCP):": "外部通訊接口一(TCP):",
|
||||
"External Port 2 (TCP+UDP):": "外部通訊接口二(TCP+UDP):",
|
||||
"Test open port (external site)": "測試開其通訊接口(外部站台)",
|
||||
"Actions ▼": "動作 ▼",
|
||||
"Active DHT nodes:": "分散式雜湊表生猛節點:",
|
||||
"Add DNS": "添加 DNS",
|
||||
"Add peer": "添加對等點",
|
||||
"ajax_error": "Ajax 錯誤:%{error}", // JavaScript error
|
||||
"All users publicly followed by": "所有用家畀公開發摟自",
|
||||
"Available": "可用", // username is available
|
||||
"Appearance": "外觀",
|
||||
"Apply": "改實",
|
||||
"Block chain information": "區塊捵資訊",
|
||||
"Block chain is up-to-date, twister is ready to use!": "區塊捵已更加新,Twister 備妥待用!",
|
||||
"Block generation": "區塊生成:",
|
||||
"busted_oh": "噢,毋!",
|
||||
"busted_avowal": "檢測到有人嘗試斟惡意材料",
|
||||
"btn_ok": "無問題",
|
||||
"Cancel": "毋做",
|
||||
'cant_get_requested_resourse': "無法嚮 %{link} 攎資源\n 狀態:%{status}。",
|
||||
"clear_cache": "清空快取",
|
||||
"Confirm": "落實",
|
||||
"сonfirm_group_leaving_header": "落實要行開谷",
|
||||
"сonfirm_group_leaving_body": "直煞要行開 %{alias} 谷嘛?",
|
||||
"confirm_switch_to_network":
|
||||
"本地守護程式尚未連綫到網絡,定抑區塊捵經已過期。\n" +
|
||||
"若果閣下待繫個頁面,閣下其動作似無效用。\n" +
|
||||
"閣下要檢查 [網絡] 狀態頁面(%{page}) 做為幫代啊?",
|
||||
"confirm_terminate_daemon": "直煞要退出守護程式嘛?\nTwister 客戶端將閘住作用。",
|
||||
"confirm_unfollow_@": "直煞要毋做發摟 @%{alias}嘛?",
|
||||
"confirm_uri_shortener_clear_cache": "直煞要清空瀏覽器其短版網址快取嘛?",
|
||||
"Change user": "更改用家",
|
||||
"Checking...": "檢查…", // checking if username is available
|
||||
"Collapse": "塌縮", // smaller view of a post
|
||||
"Configure block generation": "組襯區塊生成",
|
||||
"Connections:": "接通:", // to network
|
||||
"Connection lost.": "連綫經已掹開。",
|
||||
"daemon_is_obsolete": "Twister 守護程式過着時,必須用 %{versionReq} 或更加高版本",
|
||||
"days": "%{smart_count} 天",
|
||||
"Detailed information": "詳細資訊",
|
||||
"DHT network down.": "分散式雜湊表 網絡斷綫。",
|
||||
"Direct Messages": "私人口訊",
|
||||
"Group Messages": "谷口訊",
|
||||
"Group Messages — New Group Creation": "谷口訊 — 新谷建立",
|
||||
"Group Messages — Join Group": "谷口訊 — 埋份谷",
|
||||
"group_key_cant_import": "無法匯入私人口訊其谷密碼匙",
|
||||
"group_key_is_invalid_perhaps": "亦許密碼匙無效",
|
||||
"group_key_was_imported": "已匯入私人口訊谷 %{alias} 其密碼匙。\n"
|
||||
+"好快就能擷取到佢其口訊。",
|
||||
"direct_messages_with": "同 %{username} 其私人口訊",
|
||||
"Disable": "停用",
|
||||
"display_mentions": "顯示提及次數",
|
||||
"Display retransmissions": "顯示轉推次數",
|
||||
"DNS to obtain list of peers:": "用來攎對等點列表其 DNS:",
|
||||
"do_not_show_it_again": "再亦毋好顯示佢",
|
||||
"downloading_block_chain": "取得緊區塊捵,繼續之前請稍待 (區塊捵仍落後 %{days} 天)。",
|
||||
"download_posts_status": "已取得 %{portion} 則推文", // Downloaded 10/30 posts
|
||||
"Enable": "啟用",
|
||||
"error": "錯誤:%{error}",
|
||||
"error_connecting_to_daemon": "連綫到本地 Twister 守護程式時發生錯誤。",
|
||||
"Error in 'createwalletuser' RPC.": "繫 createwalletuser RPC 時發生錯誤。",
|
||||
"Error in 'importprivkey'": "繫 importprivkey RPC 時發生錯誤:%{rpc}",
|
||||
"Error in 'sendnewusertransaction' RPC.": "繫 sendnewusertransaction RPC 時發生錯誤。",
|
||||
"Expand": "展開", // larger view of a post
|
||||
"Favorite": "收匿",
|
||||
"File APIs not supported in this browser.": "個瀏覽器毋支援快勞應用程式界面。",
|
||||
"Follow": "發摟",
|
||||
"Following config": "發摟組襯",
|
||||
"select_way_to_follow_@": "閣下諗俾焉種方式發摟 @%{alias}",
|
||||
"Followed by": "發摟者",
|
||||
"followed_by": "畀 %{username} 發摟",
|
||||
"Followers": "發摟者",
|
||||
"Followers_of": "@%{alias} 其發摟者",
|
||||
"Following": "發摟中",
|
||||
"Following users": "發摟其用家",
|
||||
"Force connection to peer:": "夾硬接通到對等點:",
|
||||
"General information": "一般資訊",
|
||||
"Generate blocks (send promoted messages)": "產生區塊 (寄個推廣口訊)",
|
||||
"Home": "頭版", // homepage
|
||||
"hours": "%{smart_count} 個鐘",
|
||||
"Internal error: lastPostId unknown (following yourself may fix!)": "內部錯誤:lastPostId 未知 (發摟閣下自己亦許就能修正!)",
|
||||
"Known peers:": "已知對等點:",
|
||||
"Last block is ahead of your computer time, check your clock.": "最後一橛區塊經已超前着閣下其電腦時間,請檢查閣下其系統時鐘。",
|
||||
"mentions_at": "提及 @%{user}",
|
||||
"minutes": "%{smart_count} 分鐘",
|
||||
"Must be 16 characters or less.": "必須係 16 個字符或更加少。", // username
|
||||
"Network": "網絡",
|
||||
"Network config": "網絡組襯",
|
||||
"Network status": "網絡狀態",
|
||||
"New direct message...": "新淨私人口訊…",
|
||||
"New Post...": "新推文…",
|
||||
"New group": "新谷",
|
||||
"Group description": "谷斟",
|
||||
"Peers to invite": "可邀請其對等點",
|
||||
"Join group": "埋份谷",
|
||||
"Select group(s)": "繫度揀谷",
|
||||
"Create": "建立",
|
||||
"Join": "埋份",
|
||||
"Invite": "邀請",
|
||||
"Invite peers": "邀請對等點",
|
||||
"Leave group": "行開谷",
|
||||
"You got": "閣下得到",
|
||||
"in postboard": "嚮推布欄",
|
||||
"in search result": "嚮揾結果",
|
||||
"in top trends": "嚮熱門趨勢",
|
||||
"new_posts": "%{smart_count} 則新推文",
|
||||
"new_mentions": "%{smart_count} 次新提及",
|
||||
"new_direct_messages": "%{smart_count} 則新淨私人口訊",
|
||||
"new_group_messages": "%{smart_count} 則新淨谷口訊",
|
||||
"nobody": "無人", // used to promote a post without attaching the user
|
||||
"Not available": "無名可用", // username is not available
|
||||
"warn_following_not_any": "無發摟任何推友!\n請揾兼發摟某人。",
|
||||
"warn_followers_not_all": "好吧,而今尚未易其方式,得知所有發摟閣下其人。\n"
|
||||
+"計數器惟有指示已知其對等點數量,佢地正係共享閣下其推文訊流。\n"
|
||||
+"以下列表埋其推友,大多係閣下所發摟其人。",
|
||||
"warn_followers_not_all_of": "好吧,而今尚未易其方式,得知某人其所有發摟者。\n"
|
||||
+"以下列表衹埋幾個,一係係公開發摟 @%{alias} 其人。",
|
||||
"notify_desktop_error": "Twister 無法去枱面通知:發生未知錯誤。",
|
||||
"notify_desktop_perm_denied": "Twister 無法去枱面通知:權限畀拒。\n\n若果閣下要攎到通知,請繫閣下其瀏覽器設定值中,允許佢用嚮 %{this_domain}。",
|
||||
"notify_desktop_test": "冚不論都繫推文。\n歡迎閣下其添加。",
|
||||
"notify_desktop_title": "留意,呢度係 Twister!",
|
||||
"post_preview_dummy": '呢度有 *粗字*、~斜字~、-刪清綫- 同埋 _加底綫_ 其文字。\n'
|
||||
+ '同樣但例外飛起其:`*粗字*、~斜字~、-刪清綫- 同埋 _加底綫_`。\n'
|
||||
+ '連結到 [一流其圖標](%{logo}) 同埋我地華麗其站台:%{site}。',
|
||||
"Number of blocks in block chain:": "區塊捵中其區塊數量:",
|
||||
"Number of CPUs to use": "用其中央處理器數量:",
|
||||
"Only alphanumeric and underscore allowed.": "衹允許文數字同底綫。",
|
||||
"peer address": "對等點位址",
|
||||
"Private": "私人其",
|
||||
"Profile": "個人資料",
|
||||
"Postboard": "推布欄",
|
||||
"post": "推文", // verb - button to post a message
|
||||
"Post to promote:": "用來推廣其推文:",
|
||||
"Posts": "推文",
|
||||
"propagating_nickname": "將網名 %{username} 傳播到網絡…",
|
||||
"Public": "公開",
|
||||
"Refresh": "整返",
|
||||
"retransmit_this": "轉發呢則推文畀閣下其發摟者嘛?",
|
||||
"Reply": "覆返",
|
||||
"Reply...": "覆返…",
|
||||
"reply_to": "覆返畀 %{fullname}",
|
||||
"Retransmit": "轉發",
|
||||
"Retransmits": "轉發",
|
||||
"Retransmitted by": "轉發自",
|
||||
"Switch to Reply": "切換為覆返",
|
||||
"Switch to Retransmit": "切換為轉發",
|
||||
"search": "揾耶",
|
||||
"seconds": "%{smart_count} 秒",
|
||||
"send": "寄個",
|
||||
"Send post with username": "寄個推文所用其用家名稱:",
|
||||
"send_DM": "寄個私人口訊",
|
||||
"Sent Post to @": "已寄個推文畀 @",
|
||||
"Setup account": "設定戶口",
|
||||
"shorten_URI": "短版網址",
|
||||
"shorten_URI_enter_link": "輸入長版網址連結。\n"
|
||||
+"註記:短版網址將為閣下產生空其推文俾埋齊煞網址。\n"
|
||||
+"則特意推文毋會顯示嚮 Twister 客戶端,但閣下其推文計數會提返。",
|
||||
"shorten_URI_its_public_is_it_ok": "閣下其連結將係公開可讀其!直煞敢得啩?",
|
||||
"URI_shortener": "網址縮短器",
|
||||
"The File APIs are not fully supported in this browser.": "個瀏覽器兼毋完全支援快勞應用軟件界面。",
|
||||
"time_ago": "%{time} 之前", // 5 minutes ago
|
||||
"Time of the last block:": "最後一橛區塊其時間:",
|
||||
"Type message here": "繫度輸入口訊",
|
||||
"Unfollow": "毋做發摟",
|
||||
"Update": "更加新",
|
||||
"Auto updating": "自動更加新",
|
||||
'updates_are_available': '有可用更加新 ',
|
||||
'updates_not_available': '無可用更加新 ',
|
||||
'updates_check_client': '檢查有無客戶端軟件更加新 ',
|
||||
'updates_repo_overview': '而今我地係跟埋 %{repo} 分支 %{branch} 上嚮\n %{date} 其定案 %{commit}\n'
|
||||
+'但原始碼其至前緣經已位嚮\n 定案 %{commitUpstream} 其 %{dateUpstream}。',
|
||||
'updates_checkout_diff': '簽走 [GitHub 上其差異](%{link}) 來知更改着麼耶。',
|
||||
'updates_checkout_diff_nfmt': '簽走 GitHub 上其差異來知更改着麼:\n %{link}',
|
||||
'updates_upstream_isnt_changed': '相應分支其原始碼保存庫似乎無更改。',
|
||||
"Updating status...": "更加新狀態…", // status of block chain
|
||||
'new_account_briefing': '正係將新建立其戶口傳播到網絡中。'
|
||||
+'請毋好閂埋個視窗,亦許需要幾分鐘。\n\n'
|
||||
+'閣下其密碼匙係:*%{secretKey}*\n\n'
|
||||
+'強勍建議閣下利用呢段時間去保存閣下其密碼匙。'
|
||||
+'顯示來、做熒幕快照、用閣下手提電話中其影相功能,定係將佢寫繫紙上。\n\n'
|
||||
+'由毋同其電腦用個戶口時會需要密碼匙。'
|
||||
+'若果閣下一旦遺失密碼匙,閣下其戶口將永遠畀鎖住 '
|
||||
+'(註記:~ 呢係開發中軟件,佢亦許會冧而做成資料漏失 ~)。\n\n'
|
||||
+'請稍待。當閣下尚未讀煞 ~decentralization~ 之前,就會顯示「直煞」掣。',
|
||||
"user_not_yet_accepted": "遞滴對等點未接受呢位新用家。\n"+
|
||||
"好毋幸地,無法保存個人資料\n"+
|
||||
"或繫個狀態下寄個任何推文。\n\n"+
|
||||
"請稍待幾分鐘再繼續。\n\n"+
|
||||
"「保存更改」將繫處理搞直時\n"+
|
||||
"自動啟用。(我包呢係閣下\n"+
|
||||
"用 Twister 之前其最後一次\n"+
|
||||
"等待)。\n\n"+
|
||||
"秘訣:趁呢時揀閣下其頭像!",
|
||||
"users_mentions": "@%{username} 其提及次數",
|
||||
"users_profile": "%{username} 其個人資料",
|
||||
"username_undefined": "未定義其用家名稱,呢係登入要寫項目。",
|
||||
"View": "查看",
|
||||
"View All": "查看煞",
|
||||
"Who to Follow": "得發摟焉位",
|
||||
"Your message was sent!": "閣下其口訊已寄個!",
|
||||
"twister login": "Twister 登入",
|
||||
"Existing local users": "既有本地用家",
|
||||
"Or...": "或…",
|
||||
"Create a new user": "建立新用家",
|
||||
"Login": "登入",
|
||||
"Check availability": "檢查可用程度",
|
||||
"Create this nickname": "建立個網名",
|
||||
"Type nickname here": "繫度輸入網名",
|
||||
"Import secret key": "匯入密碼匙",
|
||||
"52-characters secret": "52 個字符其密碼匙",
|
||||
"With nickname": "同網名",
|
||||
"Import key": "匯入密碼匙",
|
||||
"Client Version:": "客戶端版本:",
|
||||
"Mining difficulty:": "掘礦難度:",
|
||||
"Block generation status": "區塊生成狀態",
|
||||
"Current hash rate:": "而今雜湊比率:",
|
||||
"Terminate Daemon:": "終止守護程式:",
|
||||
"Exit": "退出",
|
||||
"Save Changes": "保存更改",
|
||||
"profile_saved": "個人資料資料已畀保存到分散式雜湊表。",
|
||||
"profile_not_saved": "無法保存個人資料資料。",
|
||||
"Secret key:": "密碼匙:",
|
||||
"You have to log in to post messages.": "閣下必須登入先能推送口訊。",
|
||||
"You have to log in to post replies.": "閣下必須登入先能覆返口訊。",
|
||||
"You have to log in to retransmit messages.": "閣下必須登入先能轉發口訊。",
|
||||
"You have to log in to use direct messages.": "閣下必須登入先能用私人口訊。",
|
||||
"You have to log in to follow users.": "閣下必須登入先能發摟用家。",
|
||||
"You are not following anyone because you are not logged in.": "閣下無發摟任何人因為閣下尚未登入。",
|
||||
"You don't have any followers because you are not logged in.": "閣下無發摟者因為閣下尚未登入。",
|
||||
"No one can mention you because you are not logged in.": "無人得提及閣下因為閣下尚未登入。",
|
||||
"You don't have any profile because you are not logged in.": "閣下無個人資料因為閣下尚未登入。",
|
||||
"Options": "隨寫",
|
||||
"Switch to Promoted posts": "切換至推廣推文",
|
||||
"Switch to Normal posts": "切換至一般推文",
|
||||
"Use language": "用語言",
|
||||
"Ignore": "毋理",
|
||||
"Ignore and clear out": "毋理兼清空",
|
||||
"Theme": "布景主題",
|
||||
"Keys": "密碼匙",
|
||||
"Notifications": "通知",
|
||||
"Desktop notifications": "枱面通知",
|
||||
"Sound notifications": "聲音通知",
|
||||
"Volume": "音量",
|
||||
"Test": "測試",
|
||||
"Send key": "寄個密碼匙",
|
||||
"Posts display": "推文顯示",
|
||||
"Post editor": "推文編輯器",
|
||||
"Post preview": "推文預覽",
|
||||
"Inline image preview": "內聯錄像預覽",
|
||||
"Display": "顯示",
|
||||
"Line feeds": "送列符號",
|
||||
"Markout": "註明嘜頭",
|
||||
"Supported punctuations:": "支援其標點符號:",
|
||||
"Supported emotions:": "支援其表情符號:",
|
||||
"Supported signs:": "支援其符號:",
|
||||
"Supported fractions:": "支援其分數:",
|
||||
"Automatic unicode conversion options": "萬國碼自動轉換隨寫",
|
||||
"Convert punctuations to unicode": "轉換標點符號為萬國碼",
|
||||
"Convert emotions codes to unicode symbols": "轉換表情符號編碼為萬國碼符號",
|
||||
"Convert common signs to unicode": "轉換一般符號為萬國碼",
|
||||
"Convert fractions to unicode": "轉換分數為萬國碼",
|
||||
"Convert all": "轉換煞",
|
||||
"Auto": "自動",
|
||||
"Original": "原版",
|
||||
"none": "無",
|
||||
"Custom": "自訂",
|
||||
"Mentions": "提及",
|
||||
"Use proxy for image preview only": "代理伺服器衹用嚮錄像預覽",
|
||||
"Use external links behind a proxy": "用代理伺服器後方其外部連結",
|
||||
"There aren't any posts with this hashtag.": "無推文埋個雜湊標籤。",
|
||||
"Split only new post": "衹斬開新淨推文",
|
||||
"Split all": "斬開煞",
|
||||
"Don't split": "毋好斬開",
|
||||
"Split long posts": "斬開長其推文",
|
||||
"Posts that begin with mention": "俾提及做為開頭其推文",
|
||||
"Show all": "冚顯示",
|
||||
"Show only if I am in": "衹顯示有我其推文",
|
||||
"Show if it's between users I follow": "若果係我發摟其用家先顯示",
|
||||
"Postboard displays": "推布欄顯示",
|
||||
"RTs those are close to original twist": "同原始推文相近其轉推",
|
||||
"Show if the original is older than": "衹顯示原始推文浮頭超過",
|
||||
"hour(s)": "個鐘",
|
||||
"second(s)": "秒",
|
||||
"only positive numbers!": "衹允許正數!",
|
||||
"Language filtering": "語言篩揀",
|
||||
"By blacklist": "依照黑名單",
|
||||
"By whitelist": "依照白名單",
|
||||
"Comma separated ISO 639-3 language codes": "撩下號分隔其 ISO 639-3 語言編碼",
|
||||
"Accuracy": "準確度",
|
||||
"Simulation mode": "模擬模式",
|
||||
"This post is treated by language filter": "呢則推文由語言篩揀器所 %{treated}。",
|
||||
"blocked": "杯葛",
|
||||
"passed": "傳遞",
|
||||
"not analyzed": "無法分析",
|
||||
"Reason: this": "因由:%{this}",
|
||||
"this doesnt contain that": "%{this} 毋埋 %{that}",
|
||||
"this is undefined": "%{this} 未定義",
|
||||
"blacklist": "黑名單",
|
||||
"whitelist": "白名單",
|
||||
"language of this": "語言所屬",
|
||||
"its undefined language": "佢係種未定義其語言",
|
||||
"its this, blacklisted": "佢係 %{this},已列入黑名單",
|
||||
"its this, whitelisted": "佢係 %{this},已列入白名單",
|
||||
"Most possible language: this": "至似其語言:%{this}",
|
||||
"Scope of usage": "用其範圍",
|
||||
"Show with every user name": "每位用家都要顯示",
|
||||
"Show at profile modal only": "惟有個人資料頁面先要顯示",
|
||||
"Show if a user follows me": "發摟我其用家先顯示",
|
||||
"follows you": "發摟閣下",
|
||||
"Show conversation": "顯示會話",
|
||||
"Mark all as read": "嘜頭所有為已讀",
|
||||
"show_more_count": "%{smart_count} 更加多…",
|
||||
"hide": "匿埋",
|
||||
"Show more in this conversation...": "顯示更加多會話內容…",
|
||||
"conversation_title": "@%{username} 其會話",
|
||||
"copy_to_clipboard": "撳 Ctrl/Cmd+C 來複製,跟住撳 Enter 來閂埋",
|
||||
"Normal posts": "一般推文",
|
||||
"Promoted posts": "推廣推文",
|
||||
"Messages": "口訊",
|
||||
"Edit profile": "編輯個人資料",
|
||||
"Top Trends": "熱門趨勢",
|
||||
"Twistday Reminder": "開推周年紀念日提醒口訊",
|
||||
"Show upcoming in near future": "顯示毋耐來緊迎來慶祝其人",
|
||||
"Who's celebrating Twistday": "焉位正係慶祝開推周年紀念日",
|
||||
"Today's luckies:": "今天其幸逳兒:",
|
||||
"Upcoming ones:": "來緊迎來慶祝其人:",
|
||||
"post_rt_sign_prep": "再次推文自",
|
||||
"post_rt_time_prep": "嚮",
|
||||
"undo": "揾返",
|
||||
"Daemon exited...": "已退出守護程式…",
|
||||
"Secret Key": "密碼匙",
|
||||
"Copy to clipboard": "複製到剪貼簿",
|
||||
"Full name here": "冚名",
|
||||
"Describe yourself": "斟閣下自己",
|
||||
"Location": "地步",
|
||||
"website": "網站",
|
||||
"Tox address": "Tox 位址",
|
||||
"Bitmessage address": "Bitmessage 位址",
|
||||
"Language": "語言",
|
||||
"Sound": "聲音",
|
||||
"Users": "用家",
|
||||
"Direct Message's copy to self": "私人口訊複製畀自己",
|
||||
"Terminate Daemon": "終止守護程式",
|
||||
"New post": "新推文",
|
||||
"Search": "揾耶",
|
||||
"Direct Msg": "私人口訊",
|
||||
"Traffic information": "流量資訊",
|
||||
"DHT Torrents:": "分散式雜湊表訊流:",
|
||||
"Peers:": "對等點:",
|
||||
"Peer List Size:": "對等點列表大細:",
|
||||
"Active Requests:": "生猛請求:",
|
||||
"Download:": "取得:",
|
||||
"Upload:": "上傳:",
|
||||
"DHT Download:": "分散式雜湊表取得:",
|
||||
"DHT Upload:": "分散式雜湊表上傳:",
|
||||
"IP Overhead Download:": "互聯網協定耗費取得:",
|
||||
"IP Overhead Upload:": "互聯網協定耗費上傳:",
|
||||
"Payload Download:": "酬載取得:",
|
||||
"Payload Upload:": "酬載上傳:",
|
||||
"No favs here because you are not logged in.": "因為閣下尚未登入,呢度毋會顯示收匿。",
|
||||
"users_favs": "@%{username} 其收匿",
|
||||
"Favorites": "收匿",
|
||||
"You have to log in to favorite messages.": "閣下必須登入俾收匿口訊。",
|
||||
"fav_this": "佢為閣下所獨有嘛?",
|
||||
"Last activity": "最近一次活動",
|
||||
"New Users": "新近用家",
|
||||
"Live tracking" : "即時追蹤"
|
||||
};
|
||||
}
|
||||
|
||||
// uncomment to see all translated words replaced with filler
|
||||
//for(var word in wordset){
|
||||
// wordset[word] = "AAAA";
|
||||
|
@ -227,6 +227,10 @@ function twisterOptions() {
|
||||
name: 'dmCopySelf',
|
||||
valDefault: 'enable'
|
||||
});
|
||||
this.add({
|
||||
name: 'dmEncryptCache',
|
||||
valDefault: 'enable'
|
||||
});
|
||||
this.add({
|
||||
name: 'hideReplies',
|
||||
valDefault: 'following'
|
||||
|
@ -273,23 +273,37 @@ var router=new $.mobile.Router(
|
||||
$.mobile.showPageLoadingMsg();
|
||||
initializeTwister( true, true, function() {
|
||||
$.mobile.showPageLoadingMsg();
|
||||
requestDMsnippetList($('#directmsg .direct-messages-list'));
|
||||
modalDMsSummaryDraw($('#directmsg .direct-messages-list'));
|
||||
});
|
||||
},
|
||||
dmchat: function(type,match,ui) {
|
||||
var params=router.getParams(match[1]);
|
||||
$.mobile.showPageLoadingMsg();
|
||||
initializeTwister( true, true, function() {
|
||||
var user = params.user;
|
||||
var dmConvo = $('#dmchat .direct-messages-thread');
|
||||
$("#dmchat .rtitle").text("Chat @" + user);
|
||||
var peerAlias = params.user;
|
||||
var board = $('#dmchat .direct-messages-thread').empty();
|
||||
|
||||
$('#dmchat .rtitle').text('Chat @' + peerAlias);
|
||||
$("#dmchat textarea").val("");
|
||||
dmConvo.html("");
|
||||
installDMSendClick();
|
||||
installDMSendClick(peerAlias);
|
||||
|
||||
$.mobile.showPageLoadingMsg();
|
||||
dmChatUser = user;
|
||||
requestDmConversation(dmConvo,user);
|
||||
|
||||
tmobileQueryReq = queryStart(board, peerAlias, 'direct', undefined, 2000, {
|
||||
boardAutoAppend: true,
|
||||
lastId: 0,
|
||||
lengthNew: 0,
|
||||
ready: function (req, peerAlias) {
|
||||
twister.DMs[peerAlias] = twister.res[req];
|
||||
},
|
||||
readyReq: peerAlias,
|
||||
drawFinish: function (req) {
|
||||
setTimeout($.MAL.dmConversationLoaded, 200, twister.res[req].board);
|
||||
},
|
||||
skidoo: function (req) {
|
||||
return $.mobile.activePage.attr('id') !== 'dmchat' || req !== tmobileQueryReq;
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
search: function(type,match,ui) {
|
||||
@ -390,23 +404,21 @@ function installSubmitClick() {
|
||||
});
|
||||
}
|
||||
|
||||
function installDMSendClick() {
|
||||
var $postSubmit = $(".dm-submit");
|
||||
$postSubmit.unbind('click').click(function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
var $this = $( this );
|
||||
var $replyText = $this.closest(".post-area-new").find("textarea");
|
||||
function installDMSendClick(peerAlias) {
|
||||
$('.dm-submit').off('click').on('click', {peerAlias: peerAlias},
|
||||
function (event) {
|
||||
muteEvent(event, true);
|
||||
|
||||
var $dmConversation = $(".directMessages");
|
||||
var elemTextArea = $(event.target).closest('.post-area-new').find('textarea');
|
||||
if (!elemTextArea.val())
|
||||
return;
|
||||
|
||||
var s = encode_utf8($replyText.val());
|
||||
newDirectMsg(s, dmChatUser);
|
||||
$replyText.val("");
|
||||
});
|
||||
newDirectMsg(encode_utf8(elemTextArea.val()), event.data.peerAlias);
|
||||
elemTextArea.val('');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function installRetransmitConfirmClick() {
|
||||
var $postConfirmRt = $(".retransmit-confirm");
|
||||
$postConfirmRt.unbind('click').click(function(e){
|
||||
@ -535,15 +547,13 @@ function setupHashtagOrMention(board, query, resource) {
|
||||
$.mobile.showPageLoadingMsg();
|
||||
board.empty();
|
||||
|
||||
var req = queryStart(board, query, resource, undefined, undefined, {
|
||||
tmobileQueryReq = queryStart(board, query, resource, undefined, undefined, {
|
||||
boardAutoAppend: true,
|
||||
skidoo: function (req) {
|
||||
var curPage = $.mobile.activePage.attr('id');
|
||||
return (curPage !== 'mentions' && curPage !== 'hashtag') || req !== tmobileQueryReq;
|
||||
}
|
||||
});
|
||||
|
||||
tmobileQueryReq = req;
|
||||
}
|
||||
|
||||
// every 2 seconds do something page specific.
|
||||
@ -565,8 +575,6 @@ function tmobileTick() {
|
||||
}
|
||||
}, {} );
|
||||
}
|
||||
if (curPage === 'dmchat')
|
||||
requestDmConversation($('#dmchat .direct-messages-thread'), dmChatUser);
|
||||
}
|
||||
|
||||
$(document).bind('mobileinit', function () {
|
||||
|
@ -436,6 +436,24 @@ function updateProfilePosts(postsView, username, useGetposts) {
|
||||
});
|
||||
}
|
||||
|
||||
function queryCreateRes(query, resource, extra) {
|
||||
var req = query + '@' + resource;
|
||||
twister.res[req] = {
|
||||
query: query,
|
||||
resource: resource,
|
||||
lengthCached: 0,
|
||||
twists: {
|
||||
cached: {},
|
||||
pending: []
|
||||
}
|
||||
};
|
||||
if (extra)
|
||||
for (i in extra)
|
||||
twister.res[req][i] = extra[i];
|
||||
|
||||
return twister.res[req];
|
||||
}
|
||||
|
||||
function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra) {
|
||||
var req = query + '@' + resource;
|
||||
|
||||
@ -444,6 +462,7 @@ function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra)
|
||||
board: board,
|
||||
query: query,
|
||||
resource: resource,
|
||||
lengthCached: 0,
|
||||
twists: {
|
||||
cached: {},
|
||||
pending: []
|
||||
@ -462,6 +481,15 @@ function queryStart(board, query, resource, timeoutArgs, intervalTimeout, extra)
|
||||
if (twister.res[req].twists.pending.indexOf(i) === -1)
|
||||
twister.res[req].twists.pending.push(i);
|
||||
|
||||
if (extra) {
|
||||
if (typeof extra.drawFinish === 'function') {
|
||||
twister.res[req].drawFinish = extra.drawFinish;
|
||||
twister.res[req].drawFinishReq = extra.drawFinishReq;
|
||||
}
|
||||
if (typeof extra.skidoo === 'function')
|
||||
twister.res[req].skidoo = extra.skidoo;
|
||||
}
|
||||
|
||||
queryPendingDraw(req);
|
||||
}
|
||||
|
||||
@ -510,27 +538,45 @@ function queryRequest(req) {
|
||||
} else if (twister.res[req].resource === 'fav')
|
||||
twisterRpc('getfavs', [twister.res[req].query, 1000],
|
||||
queryProcess, req);
|
||||
else
|
||||
else if (twister.res[req].resource === 'direct') {
|
||||
var lengthStandard = 100; // FIXME there may be the gap between .lastId and the lesser twist.id in response greater than 100 (very rare case)
|
||||
if (twister.res[req].lengthCached < Math.min(twister.res[req].lastId, lengthStandard)
|
||||
&& !twister.res[req].triedToReCache) {
|
||||
twister.res[req].triedToReCache = true;
|
||||
var length = Math.min(twister.res[req].lastId + 1, lengthStandard);
|
||||
var query = [{username: twister.res[req].query, max_id: twister.res[req].lastId}];
|
||||
} else
|
||||
var length = lengthStandard, query = [{username: twister.res[req].query, since_id: twister.res[req].lastId}];
|
||||
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, length, query],
|
||||
queryProcess, req,
|
||||
function (req, res) {
|
||||
console.warn(polyglot.t('ajax_error', {error: (res && res.message) ? res.message : res}));
|
||||
}
|
||||
);
|
||||
} else
|
||||
dhtget(twister.res[req].query, twister.res[req].resource, 'm',
|
||||
queryProcess, req, twister.res[req].timeoutArgs);
|
||||
}
|
||||
|
||||
function queryProcess(req, twists) {
|
||||
if (!req || !twister.res[req] || !twists || !twists.length)
|
||||
function queryProcess(req, res) {
|
||||
if (!req || !twister.res[req] || typeof res !== 'object' || $.isEmptyObject(res))
|
||||
return;
|
||||
|
||||
var lengthNew = 0;
|
||||
var lengthPending = twister.res[req].twists.pending.length;
|
||||
|
||||
if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName)
|
||||
lengthNew = queryPendingPushMentions(req, twists);
|
||||
lengthNew = queryPendingPushMentions(req, res);
|
||||
else if (twister.res[req].resource === 'direct')
|
||||
lengthNew = queryPendingPushDMs(res);
|
||||
else
|
||||
lengthNew = queryPendingPush(req, twists);
|
||||
lengthNew = queryPendingPush(req, res);
|
||||
|
||||
if (typeof twister.res[req].skidoo === 'function' && twister.res[req].skidoo(req))
|
||||
return;
|
||||
|
||||
if (lengthNew)
|
||||
if (lengthNew) {
|
||||
if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName) {
|
||||
$.MAL.updateNewMentionsUI(twister.res[req].lengthNew);
|
||||
$.MAL.soundNotifyMentions();
|
||||
@ -550,6 +596,25 @@ function queryProcess(req, twists) {
|
||||
$.MAL.showMentions(defaultScreenName);
|
||||
}).bind({req: req})
|
||||
});
|
||||
} else if (twister.res[req].resource === 'direct') {
|
||||
if (twister.res[req].query[0] !== '*')
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
else
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
|
||||
$.MAL.soundNotifyDM();
|
||||
if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable')
|
||||
$.MAL.showDesktopNotification({
|
||||
body: twister.res[req].query[0] === '*' ?
|
||||
polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', getNewGroupDMsCount()) + '.'
|
||||
: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', getNewDMsCount()) + '.',
|
||||
tag: 'twister_notification_new_DMs',
|
||||
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
||||
funcClick: (function () {
|
||||
focusModalWithElement(twister.res[this.req].board);
|
||||
}).bind({req: req})
|
||||
});
|
||||
// TODO new DMs counters on minimized modals'
|
||||
} else if (!$.mobile && $.Options.showDesktopNotifPostsModal.val === 'enable'
|
||||
&& (twister.res[req].resource !== 'mention' || twister.res[req].query !== defaultScreenName)
|
||||
&& twister.res[req].board && isModalWithElemExists(twister.res[req].board)
|
||||
@ -559,7 +624,7 @@ function queryProcess(req, twists) {
|
||||
+ polyglot.t('in search result') + '.',
|
||||
tag: 'twister_notification_new_posts_modal',
|
||||
timeout: $.Options.showDesktopNotifPostsModalTimer.val,
|
||||
funcClick: (function() {
|
||||
funcClick: (function () {
|
||||
focusModalWithElement(twister.res[this.req].board,
|
||||
function (req) {
|
||||
twister.res[req].board.closest('.postboard')
|
||||
@ -569,6 +634,7 @@ function queryProcess(req, twists) {
|
||||
);
|
||||
}).bind({req: req})
|
||||
});
|
||||
}
|
||||
|
||||
if (twister.res[req].twists.pending.length > lengthPending) { // there is some twists may be which are not considered new so lengthNew equals zero (mentions thing)
|
||||
if (!twister.res[req].board || (!$.mobile && !isModalWithElemExists(twister.res[req].board)))
|
||||
@ -619,6 +685,7 @@ function queryPendingPush(req, twists) {
|
||||
|
||||
lengthNew++;
|
||||
twister.res[req].twists.cached[j] = twists[i];
|
||||
twister.res[req].lengthCached++;
|
||||
twister.res[req].twists.pending.push(j);
|
||||
}
|
||||
}
|
||||
@ -627,13 +694,57 @@ function queryPendingPush(req, twists) {
|
||||
}
|
||||
|
||||
function queryPendingDraw(req) {
|
||||
var twists = [];
|
||||
for (var i = 0; i < twister.res[req].twists.pending.length; i++)
|
||||
twists.push(twister.res[req].twists.cached[twister.res[req].twists.pending[i]]);
|
||||
var twists = [], length = 0;
|
||||
|
||||
attachPostsToStream(twister.res[req].board, twists, false);
|
||||
if (twister.res[req].resource === 'direct') {
|
||||
for (var j = 0; j < twister.res[req].twists.pending.length; j++) {
|
||||
var twist = twister.res[req].twists.cached[twister.res[req].twists.pending[j]];
|
||||
for (var i = 0; i < length; i++)
|
||||
if (twist.id < twists[i].id) {
|
||||
twists.splice(i, 0, twist);
|
||||
break;
|
||||
}
|
||||
|
||||
if (length === twists.length)
|
||||
twists.push(twist);
|
||||
|
||||
length++;
|
||||
}
|
||||
attachPostsToStream(twister.res[req].board, twists, false,
|
||||
function (twist, req) {
|
||||
return {item: postToElemDM(twist, req.peerAliasLocal, req.peerAliasRemote)
|
||||
.attr('data-id', twist.id), time: twist.time};
|
||||
},
|
||||
{peerAliasLocal: defaultScreenName, peerAliasRemote: twister.res[req].query}
|
||||
);
|
||||
resetNewDMsCountForPeer(twister.res[req].query);
|
||||
} else {
|
||||
for (var j = 0; j < twister.res[req].twists.pending.length; j++) {
|
||||
var twist = twister.res[req].twists.cached[twister.res[req].twists.pending[j]];
|
||||
for (var i = 0; i < length; i++)
|
||||
if (twist.userpost.time > twists[i].userpost.time) {
|
||||
twists.splice(i, 0, twist);
|
||||
break;
|
||||
}
|
||||
|
||||
if (length === twists.length)
|
||||
twists.push(twist);
|
||||
|
||||
length++;
|
||||
}
|
||||
attachPostsToStream(twister.res[req].board, twists, true,
|
||||
function (twist) {
|
||||
return {item: postToElem(twist, 'original'), time: twist.userpost.time};
|
||||
}
|
||||
);
|
||||
if (twister.res[req].resource === 'mention' && twister.res[req].query === defaultScreenName)
|
||||
resetMentionsCount();
|
||||
}
|
||||
|
||||
queryPendingClear(req);
|
||||
|
||||
$.MAL.postboardLoaded();
|
||||
if (typeof twister.res[req].drawFinish === 'function')
|
||||
twister.res[req].drawFinish(req, twister.res[req].drawFinishReq);
|
||||
else
|
||||
$.MAL.postboardLoaded();
|
||||
}
|
||||
|
@ -5,120 +5,6 @@
|
||||
|
||||
var _groupMsgInviteToGroupQueue = [];
|
||||
|
||||
function requestDMsnippetList(elemList, forGroup) {
|
||||
var followList = [];
|
||||
for (var i = 0; i < followingUsers.length; i++)
|
||||
followList.push({username: followingUsers[i]});
|
||||
for (var i = 0; i < groupChatAliases.length; i++)
|
||||
followList.push({username: groupChatAliases[i]});
|
||||
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList],
|
||||
processDMsnippet, {elemList: elemList, forGroup: forGroup},
|
||||
function(req, ret) {console.log('ajax error:' + ret);}, null
|
||||
);
|
||||
}
|
||||
|
||||
function processDMsnippet(req, DMs) {
|
||||
req.elemList.empty();
|
||||
|
||||
for (var alias in DMs)
|
||||
if ((req.forGroup && alias[0] === '*') || (!req.forGroup && alias[0] !== '*'))
|
||||
addToCommonDMsList(req.elemList, alias, DMs[alias][0]);
|
||||
|
||||
$.MAL.commonDMsListLoaded();
|
||||
}
|
||||
|
||||
function requestDmConversationModal(postboard, peerAlias) {
|
||||
if (!isModalWithElemExists(postboard))
|
||||
return;
|
||||
|
||||
requestDmConversation(postboard, peerAlias);
|
||||
setTimeout(requestDmConversationModal, 1000, postboard, peerAlias);
|
||||
}
|
||||
|
||||
function requestDmConversation(postboard, peerAlias) {
|
||||
var since_id = undefined;
|
||||
|
||||
var oldItems = postboard.children();
|
||||
if (oldItems.length)
|
||||
since_id = parseInt(oldItems.eq(oldItems.length - 1).attr('data-id'));
|
||||
|
||||
var userDmReq = [{username: peerAlias}];
|
||||
if (typeof since_id !== 'undefined')
|
||||
userDmReq[0].since_id = since_id;
|
||||
|
||||
var count = 100;
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, count, userDmReq],
|
||||
function(req, ret) {processDmConversation(req.postboard, req.peerAlias, ret);},
|
||||
{postboard: postboard, peerAlias: peerAlias},
|
||||
function(req, ret) {
|
||||
var msg = (ret.message) ? ret.message : ret;
|
||||
alert(polyglot.t('ajax_error', {error: msg}));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function processDmConversation(stream, peerAlias, posts) {
|
||||
if (!isModalWithElemExists(stream))
|
||||
return;
|
||||
|
||||
var streamItems = stream.children();
|
||||
var streamPostsIDs = [];
|
||||
var newPosts = 0;
|
||||
|
||||
for (var i = 0; i < streamItems.length; i++) {
|
||||
streamPostsIDs.push(parseInt(streamItems.eq(i).attr('data-id')));
|
||||
}
|
||||
|
||||
if (posts[peerAlias] && posts[peerAlias].length) {
|
||||
for (var i = 0; i < posts[peerAlias].length; i++) {
|
||||
if (streamPostsIDs.indexOf(posts[peerAlias][i].id) === -1) {
|
||||
var lastPostID = posts[peerAlias][i].id;
|
||||
newPosts++;
|
||||
postToElemDM(posts[peerAlias][i], defaultScreenName, peerAlias)
|
||||
.attr('data-id', lastPostID)
|
||||
.appendTo(stream)
|
||||
;
|
||||
streamPostsIDs.push(lastPostID);
|
||||
}
|
||||
}
|
||||
$.MAL.dmConversationLoaded(stream);
|
||||
}
|
||||
|
||||
if (newPosts) {
|
||||
resetNewDMsCountForUser(peerAlias, lastPostID);
|
||||
|
||||
if (getHashOfMinimizedModalWithElem(stream)) {
|
||||
$.MAL.soundNotifyDM();
|
||||
_newDMsPerUser[peerAlias] += newPosts;
|
||||
if (peerAlias[0] === '*')
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
else
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
|
||||
if (!$.hasOwnProperty('mobile') && $.Options.showDesktopNotifDMs.val === 'enable')
|
||||
$.MAL.showDesktopNotification({
|
||||
body: peerAlias[0] === '*' ?
|
||||
polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newPosts) + '.'
|
||||
: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newPosts) + '.',
|
||||
tag: 'twister_notification_new_DMs',
|
||||
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
||||
funcClick: (function() {
|
||||
focusModalWithElement(this.postboard,
|
||||
function (peerAlias) {
|
||||
_newDMsPerUser[peerAlias] = 0;
|
||||
if (peerAlias[0] === '*')
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
else
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
}, this.peerAlias);
|
||||
}).bind({postboard: stream, peerAlias: peerAlias})
|
||||
});
|
||||
// TODO here we need to set new DMs counter on minimized modal button
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function directMsgSubmit(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@ -161,6 +47,20 @@ function newDirectMsg(msg, peerAlias) {
|
||||
alert(polyglot.t('Internal error: lastPostId unknown (following yourself may fix!)'));
|
||||
}
|
||||
|
||||
function modalDMsSummaryDraw(elem, group) {
|
||||
elem.empty();
|
||||
|
||||
for (var peerAlias in twister.DMs)
|
||||
if (group ? peerAlias[0] === '*' : peerAlias[0] !== '*')
|
||||
for (var j in twister.DMs[peerAlias].twists.cached)
|
||||
if (twister.DMs[peerAlias].lastId === twister.DMs[peerAlias].twists.cached[j].id) {
|
||||
addToCommonDMsList(elem, peerAlias, twister.DMs[peerAlias].twists.cached[j]);
|
||||
break;
|
||||
}
|
||||
|
||||
$.MAL.commonDMsListLoaded();
|
||||
}
|
||||
|
||||
// dispara o modal de direct messages
|
||||
function openCommonDMsModal() {
|
||||
if (!defaultScreenName) {
|
||||
@ -174,19 +74,16 @@ function openCommonDMsModal() {
|
||||
title: polyglot.t('Direct Messages')
|
||||
});
|
||||
|
||||
requestDMsnippetList(modal.content.find('.direct-messages-list'));
|
||||
modalDMsSummaryDraw(modal.content.find('.direct-messages-list'));
|
||||
|
||||
modal.self.find('.mark-all-as-read')
|
||||
.css('display', 'inline')
|
||||
.attr('title', polyglot.t('Mark all as read'))
|
||||
.on('click', function (event) {
|
||||
for (var user in _newDMsPerUser) {
|
||||
if (user[0] !== '*')
|
||||
_newDMsPerUser[user] = 0;
|
||||
}
|
||||
saveDMsToStorage();
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
$(event.target).closest('.directMessages').find('.direct-messages-list .messages-qtd').hide();
|
||||
resetNewDMsCount();
|
||||
var elem = $(event.target).closest('.directMessages').find('.direct-messages-list');
|
||||
elem.find('.messages-qtd').hide();
|
||||
elem.find('.post.new').removeClass('new');
|
||||
})
|
||||
;
|
||||
}
|
||||
@ -210,7 +107,21 @@ function openDmWithUserModal(peerAlias) {
|
||||
else
|
||||
getFullname(peerAlias, modal.self.find('.modal-header h3 span'));
|
||||
|
||||
requestDmConversationModal(modal.self.find('.direct-messages-thread').empty(), peerAlias);
|
||||
queryStart(modal.content.find('.direct-messages-thread'),
|
||||
peerAlias, 'direct', undefined, 2000, {
|
||||
boardAutoAppend: true,
|
||||
lastId: 0,
|
||||
lengthNew: 0,
|
||||
ready: function (req, peerAlias) {
|
||||
twister.DMs[peerAlias] = twister.res[req];
|
||||
},
|
||||
readyReq: peerAlias,
|
||||
drawFinish: function (req) {
|
||||
$.MAL.dmConversationLoaded(twister.res[req].board);
|
||||
}
|
||||
}
|
||||
);
|
||||
modal.content.on('scroll', {req: peerAlias}, handleDMsModalScroll);
|
||||
|
||||
$('.dm-form-template').children().clone(true)
|
||||
.addClass('open').appendTo(modal.content).fadeIn('fast')
|
||||
@ -232,19 +143,16 @@ function openGroupMessagesModal(groupAlias) {
|
||||
|
||||
modal.content.prepend($('#group-messages-profile-modal-control-template').children().clone(true));
|
||||
|
||||
requestDMsnippetList(modal.content.find('.direct-messages-list'), true);
|
||||
modalDMsSummaryDraw(modal.content.find('.direct-messages-list'), true);
|
||||
|
||||
modal.self.find('.mark-all-as-read')
|
||||
.css('display', 'inline')
|
||||
.attr('title', polyglot.t('Mark all as read'))
|
||||
.on('click', function (event) {
|
||||
for (var user in _newDMsPerUser) {
|
||||
if (user[0] === '*')
|
||||
_newDMsPerUser[user] = 0;
|
||||
}
|
||||
saveDMsToStorage();
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
$(event.target).closest('.groupMessages').find('.direct-messages-list .messages-qtd').hide();
|
||||
resetNewDMsCountGroup();
|
||||
var elem = $(event.target).closest('.groupMessages').find('.direct-messages-list');
|
||||
elem.find('.messages-qtd').hide();
|
||||
elem.find('.post.new').removeClass('new');
|
||||
})
|
||||
;
|
||||
} else {
|
||||
@ -261,7 +169,21 @@ function openGroupMessagesModal(groupAlias) {
|
||||
function(req, ret) {
|
||||
if (ret && ret.members.indexOf(defaultScreenName) !== -1) {
|
||||
req.modal.content.append($('.messages-thread-template').children().clone(true));
|
||||
requestDmConversationModal(req.modal.content.find('.direct-messages-thread'), req.groupAlias);
|
||||
queryStart(req.modal.content.find('.direct-messages-thread'),
|
||||
req.groupAlias, 'direct', undefined, 2000, {
|
||||
boardAutoAppend: true,
|
||||
lastId: 0,
|
||||
lengthNew: 0,
|
||||
ready: function (req, peerAlias) {
|
||||
twister.DMs[peerAlias] = twister.res[req];
|
||||
},
|
||||
readyReq: req.groupAlias,
|
||||
drawFinish: function (req) {
|
||||
$.MAL.dmConversationLoaded(twister.res[req].board);
|
||||
}
|
||||
}
|
||||
);
|
||||
modal.content.on('scroll', {req: req.groupAlias}, handleDMsModalScroll);
|
||||
|
||||
var control = $('#group-messages-messages-modal-control-template').children().clone(true)
|
||||
.appendTo(req.modal.content);
|
||||
|
@ -266,10 +266,10 @@ function setPostInfoSent(n, k, item) {
|
||||
// format dmdata (returned by getdirectmsgs) to display in conversation thread
|
||||
function postToElemDM(dmData, localUser, remoteUser) {
|
||||
var senderAlias = (dmData.from && dmData.from.length && dmData.from.charCodeAt(0))
|
||||
? dmData.from : (dmData.fromMe ? localUser : remoteUser);
|
||||
? dmData.from : (dmData.fromMe || dmData.from === localUser ? localUser : remoteUser);
|
||||
var elem = $('#dm-chat-template').clone(true).appendTo(twister.html.detached)
|
||||
.removeAttr('id')
|
||||
.addClass(dmData.fromMe ? 'sent' : 'received')
|
||||
.addClass(dmData.fromMe || dmData.from === localUser ? 'sent' : 'received')
|
||||
;
|
||||
|
||||
var elemName = elem.find('.post-info-name')
|
||||
|
@ -42,6 +42,7 @@ function loadMentionsFromStorage() {
|
||||
var j = mentions.twists[i].userpost.n + '/' + mentions.twists[i].userpost.time;
|
||||
if (typeof twister.mentions.twists.cached[j] === 'undefined') {
|
||||
twister.mentions.twists.cached[j] = mentions.twists[i];
|
||||
twister.mentions.lengthCached++;
|
||||
if (twister.mentions.twists.cached[j].isNew)
|
||||
twister.mentions.lengthNew++;
|
||||
|
||||
@ -61,6 +62,7 @@ function loadMentionsFromStorage() {
|
||||
var j = mentions[i].data.userpost.n + '/' + mentions[i].mentionTime;
|
||||
if (typeof twister.mentions.twists.cached[j] === 'undefined') {
|
||||
twister.mentions.twists.cached[j] = mentions[i].data;
|
||||
twister.mentions.lengthCached++;
|
||||
if (twister.mentions.twists.cached[j].isNew)
|
||||
twister.mentions.lengthNew++;
|
||||
|
||||
@ -104,6 +106,7 @@ function queryPendingPushMentions(req, res) {
|
||||
var j = res[i].userpost.n + '/' + res[i].userpost.time;
|
||||
if (typeof twister.res[req].twists.cached[j] === 'undefined') {
|
||||
twister.res[req].twists.cached[j] = res[i];
|
||||
twister.res[req].lengthCached++;
|
||||
twister.res[req].twists.pending.push(j);
|
||||
|
||||
// mention must be somewhat recent compared to last known one to be considered new
|
||||
@ -125,6 +128,9 @@ function queryPendingPushMentions(req, res) {
|
||||
}
|
||||
|
||||
function resetMentionsCount() {
|
||||
if (!twister.mentions.lengthNew)
|
||||
return;
|
||||
|
||||
twister.mentions.lengthNew = 0;
|
||||
|
||||
for (var j in twister.mentions.twists.cached)
|
||||
@ -159,10 +165,10 @@ function handleMentionsModalScroll(event) {
|
||||
if (elem.scrollTop() >= elem[0].scrollHeight - elem.height() - 50) {
|
||||
twister.mentions.scrollQueryActive = true;
|
||||
|
||||
twisterRpc('getmentions', [twister.mentions.query, 10,
|
||||
twisterRpc('getmentions', [twister.mentions.query, postsPerRefresh,
|
||||
{max_id: twister.mentions.lastTorrentId - twister.mentions.lengthFromTorrent}],
|
||||
function (req, res) {
|
||||
twister.mentions.scrollQueryActive = false;
|
||||
twister.res[req].scrollQueryActive = false;
|
||||
twister.res[req].boardAutoAppend = true; // FIXME all pending twists will be appended
|
||||
queryProcess(req, res);
|
||||
twister.res[req].boardAutoAppend = false;
|
||||
@ -174,116 +180,301 @@ function handleMentionsModalScroll(event) {
|
||||
|
||||
// --- direct messages ---
|
||||
|
||||
var _lastDMIdPerUser = {};
|
||||
var _newDMsPerUser = {};
|
||||
|
||||
function saveDMsToStorage() {
|
||||
var ns = $.initNamespaceStorage(defaultScreenName);
|
||||
ns.localStorage.set('lastDMIdPerUser', _lastDMIdPerUser);
|
||||
ns.localStorage.set('newDMsPerUser', _newDMsPerUser);
|
||||
var pool = {};
|
||||
|
||||
for (var peerAlias in twister.DMs) {
|
||||
var twists = [], length = 0;
|
||||
for (var j in twister.DMs[peerAlias].twists.cached) {
|
||||
for (var i = 0; i < length; i++)
|
||||
if (twister.DMs[peerAlias].twists.cached[j].id > twists[i].id) {
|
||||
twists.splice(i, 0, twister.DMs[peerAlias].twists.cached[j]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (length === twists.length)
|
||||
twists.push(twister.DMs[peerAlias].twists.cached[j]);
|
||||
|
||||
length++;
|
||||
}
|
||||
pool[peerAlias] = {
|
||||
twists: twists.slice(0, 100), // TODO add an option to specify number of DMs to cache
|
||||
lastId: twister.DMs[peerAlias].lastId,
|
||||
};
|
||||
}
|
||||
|
||||
if ($.Options.get('dmEncryptCache') === 'enable') {
|
||||
pool = twister.var.key.pub.encrypt(JSON.stringify(pool));
|
||||
delete pool.orig; // WORKAROUND the decrypt function does .slice(0, orig) but something goes wrong in process of buffer decoding (if original string contains non-ASCII characters) and orig may be smaller than the actual size, if it is undefined .slice gets it whole
|
||||
}
|
||||
$.initNamespaceStorage(defaultScreenName).localStorage.set('DMs', pool);
|
||||
}
|
||||
|
||||
function loadDMsFromStorage() {
|
||||
var ns = $.initNamespaceStorage(defaultScreenName);
|
||||
if (ns.localStorage.isSet('lastDMIdPerUser'))
|
||||
_lastDMIdPerUser = ns.localStorage.get('lastDMIdPerUser');
|
||||
if (ns.localStorage.isSet('newDMsPerUser'))
|
||||
_newDMsPerUser = ns.localStorage.get('newDMsPerUser');
|
||||
var storage = $.initNamespaceStorage(defaultScreenName).localStorage;
|
||||
|
||||
if (storage.isSet('DMs')) {
|
||||
var pool = storage.get('DMs');
|
||||
if (pool.key && pool.body && pool.mac) {
|
||||
if (pool = twister.var.key.decrypt(pool))
|
||||
pool = JSON.parse(pool.toString());
|
||||
else
|
||||
console.warn('can\'t decrypt DMs\' data cache');
|
||||
}
|
||||
if (typeof pool === 'object') {
|
||||
for (var peerAlias in pool) {
|
||||
if (!twister.DMs[peerAlias])
|
||||
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
|
||||
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
|
||||
|
||||
for (var i = 0; i < pool[peerAlias].twists.length; i++) {
|
||||
var j = pool[peerAlias].twists[i].from + '/' + pool[peerAlias].twists[i].time;
|
||||
if (typeof twister.DMs[peerAlias].twists.cached[j] === 'undefined') {
|
||||
twister.DMs[peerAlias].twists.cached[j] = pool[peerAlias].twists[i];
|
||||
twister.DMs[peerAlias].lengthCached++;
|
||||
if (twister.DMs[peerAlias].twists.cached[j].isNew)
|
||||
twister.DMs[peerAlias].lengthNew++;
|
||||
}
|
||||
}
|
||||
twister.DMs[peerAlias].lastId = pool[peerAlias].lastId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WARN all following storage keys are deprecated (see commit FIXME)
|
||||
if (storage.isSet('lastDMIdPerUser')) {
|
||||
var pool = storage.get('lastDMIdPerUser');
|
||||
if (typeof pool === 'object')
|
||||
for (var peerAlias in pool) {
|
||||
if (!twister.DMs[peerAlias])
|
||||
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
|
||||
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
|
||||
|
||||
twister.DMs[peerAlias].lastId = pool[peerAlias];
|
||||
}
|
||||
|
||||
storage.remove('lastDMIdPerUser');
|
||||
}
|
||||
if (storage.isSet('newDMsPerUser')) {
|
||||
var pool = storage.get('newDMsPerUser');
|
||||
if (typeof pool === 'object')
|
||||
for (var peerAlias in pool) {
|
||||
if (!twister.DMs[peerAlias])
|
||||
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
|
||||
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
|
||||
|
||||
twister.DMs[peerAlias].lengthNew = pool[peerAlias];
|
||||
}
|
||||
|
||||
storage.remove('newDMsPerUser');
|
||||
}
|
||||
}
|
||||
|
||||
function queryPendingPushDMs(res) {
|
||||
var lengthNew = 0;
|
||||
var lengthPending = 0;
|
||||
|
||||
for (var peerAlias in res) {
|
||||
if (!res[peerAlias] || !res[peerAlias].length || !twister.DMs[peerAlias])
|
||||
continue;
|
||||
|
||||
for (var i = 0; i < res[peerAlias].length; i++) {
|
||||
var j = res[peerAlias][i].from + '/' + res[peerAlias][i].time;
|
||||
if (typeof twister.DMs[peerAlias].twists.cached[j] === 'undefined') {
|
||||
twister.DMs[peerAlias].twists.cached[j] = res[peerAlias][i];
|
||||
twister.DMs[peerAlias].lengthCached++;
|
||||
twister.DMs[peerAlias].twists.pending.push(j);
|
||||
lengthPending++;
|
||||
if (twister.DMs[peerAlias].lastId < res[peerAlias][i].id) {
|
||||
twister.DMs[peerAlias].lastId = res[peerAlias][i].id;
|
||||
if ((!twister.DMs[peerAlias].board || !twister.DMs[peerAlias].board.is('html *'))
|
||||
&& !res[peerAlias][i].fromMe && res[peerAlias][i].from !== defaultScreenName) {
|
||||
lengthNew++;
|
||||
twister.DMs[peerAlias].lengthNew += 1;
|
||||
twister.DMs[peerAlias].twists.cached[j].isNew = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lengthPending)
|
||||
saveDMsToStorage();
|
||||
|
||||
return lengthNew;
|
||||
}
|
||||
|
||||
function requestDMsCount() {
|
||||
var followList = [];
|
||||
var list = [];
|
||||
for (var i = 0; i < followingUsers.length; i++)
|
||||
followList.push({username: followingUsers[i]});
|
||||
for (var i = 0; i < groupChatAliases.length; i++ )
|
||||
followList.push({username: groupChatAliases[i]});
|
||||
list.push({username: followingUsers[i]});
|
||||
for (var i = 0; i < groupChatAliases.length; i++)
|
||||
list.push({username: groupChatAliases[i]});
|
||||
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, 1, followList],
|
||||
function(req, dmUsers) {
|
||||
var newDMsUpdated;
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, 1, list],
|
||||
function (req, res) {
|
||||
var lengthNew = 0, lengthNewMax = 0;
|
||||
var list = [];
|
||||
|
||||
for (var u in dmUsers) {
|
||||
if (dmUsers[u]) {
|
||||
var dmData = dmUsers[u][0];
|
||||
if (u in _lastDMIdPerUser && u in _newDMsPerUser) {
|
||||
if (dmData.id !== _lastDMIdPerUser[u]) {
|
||||
_newDMsPerUser[u] += dmData.id - _lastDMIdPerUser[u];
|
||||
newDMsUpdated = true;
|
||||
}
|
||||
} else {
|
||||
_newDMsPerUser[u] = dmData.id + 1;
|
||||
newDMsUpdated = true;
|
||||
}
|
||||
_lastDMIdPerUser[u] = dmData.id;
|
||||
}
|
||||
for (var peerAlias in res) {
|
||||
if (!res[peerAlias] || !res[peerAlias].length)
|
||||
continue;
|
||||
|
||||
if (!twister.DMs[peerAlias])
|
||||
twister.DMs[peerAlias] = queryCreateRes(peerAlias, 'direct',
|
||||
{boardAutoAppend: true, lastId: 0, lengthNew: 0});
|
||||
|
||||
if (res[peerAlias][0].id > twister.DMs[peerAlias].lastId) {
|
||||
lengthNew = res[peerAlias][0].id - twister.DMs[peerAlias].lastId;
|
||||
if (lengthNewMax < lengthNew)
|
||||
lengthNewMax = lengthNew;
|
||||
|
||||
list.push({username: peerAlias});
|
||||
} else if (!twister.DMs[peerAlias].lengthCached)
|
||||
queryPendingPushDMs(res);
|
||||
}
|
||||
if (newDMsUpdated) {
|
||||
saveDMsToStorage();
|
||||
var newDMs = getNewDMsCount();
|
||||
if (newDMs) {
|
||||
$.MAL.updateNewDMsUI(newDMs);
|
||||
$.MAL.soundNotifyDM();
|
||||
|
||||
if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') {
|
||||
$.MAL.showDesktopNotification({
|
||||
body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', newDMs) + '.',
|
||||
tag: 'twister_notification_new_DMs',
|
||||
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
||||
funcClick: function () {$.MAL.showDMchat();}
|
||||
});
|
||||
}
|
||||
}
|
||||
var newDMs = getNewGroupDMsCount();
|
||||
if (newDMs) {
|
||||
$.MAL.updateNewGroupDMsUI(newDMs);
|
||||
$.MAL.soundNotifyDM();
|
||||
if (list.length === 1)
|
||||
queryProcess(list[0].username + '@direct', res);
|
||||
else if (lengthNewMax === 1) {
|
||||
if (queryPendingPushDMs(res))
|
||||
DMsSummaryProcessNew();
|
||||
} else if (lengthNewMax) {
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, lengthNewMax, list],
|
||||
function (req, res) {
|
||||
if (typeof res !== 'object' || $.isEmptyObject(res))
|
||||
return;
|
||||
|
||||
if (!$.mobile && $.Options.showDesktopNotifDMs.val === 'enable') {
|
||||
$.MAL.showDesktopNotification({
|
||||
body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', newDMs) + '.',
|
||||
tag: 'twister_notification_new_DMs',
|
||||
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
||||
funcClick: function () {$.MAL.showDMchat({group: true});}
|
||||
});
|
||||
if (queryPendingPushDMs(res))
|
||||
DMsSummaryProcessNew();
|
||||
}, undefined,
|
||||
function (req, res) {
|
||||
console.warn(polyglot.t('ajax_error',
|
||||
{error: (res && res.message) ? res.message : res}));
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}, null,
|
||||
function(req, ret) {console.warn('ajax error:' + ret);}, null
|
||||
}, undefined,
|
||||
function (req, res) {
|
||||
console.warn(polyglot.t('ajax_error', {error: (res && res.message) ? res.message : res}));
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getNewDMsCount() {
|
||||
var newDMs = 0;
|
||||
|
||||
for (var user in _newDMsPerUser) {
|
||||
if (user[0] !== '*' && _newDMsPerUser[user])
|
||||
newDMs += _newDMsPerUser[user];
|
||||
function DMsSummaryProcessNew() {
|
||||
var lengthNew = getNewDMsCount();
|
||||
if (lengthNew) {
|
||||
$.MAL.updateNewDMsUI(lengthNew);
|
||||
$.MAL.soundNotifyDM();
|
||||
if (!$.mobile) {
|
||||
if ($.Options.showDesktopNotifDMs.val === 'enable') {
|
||||
$.MAL.showDesktopNotification({
|
||||
body: polyglot.t('You got') + ' ' + polyglot.t('new_direct_messages', lengthNew) + '.',
|
||||
tag: 'twister_notification_new_DMs',
|
||||
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
||||
funcClick: function () {$.MAL.showDMchat();}
|
||||
});
|
||||
}
|
||||
var elem = getElem('.directMessages .direct-messages-list');
|
||||
if (isModalWithElemExists(elem))
|
||||
modalDMsSummaryDraw(elem);
|
||||
} else if ($.mobile.activePage.attr('id') !== 'directmsg')
|
||||
modalDMsSummaryDraw($('#directmsg .direct-messages-list'));
|
||||
}
|
||||
lengthNew = getNewGroupDMsCount();
|
||||
if (lengthNew) {
|
||||
$.MAL.updateNewGroupDMsUI(lengthNew);
|
||||
$.MAL.soundNotifyDM();
|
||||
if (!$.mobile) {
|
||||
if ($.Options.showDesktopNotifDMs.val === 'enable') {
|
||||
$.MAL.showDesktopNotification({
|
||||
body: polyglot.t('You got') + ' ' + polyglot.t('new_group_messages', lengthNew) + '.',
|
||||
tag: 'twister_notification_new_DMs',
|
||||
timeout: $.Options.showDesktopNotifDMsTimer.val,
|
||||
funcClick: function () {$.MAL.showDMchat({group: true});}
|
||||
});
|
||||
}
|
||||
var elem = getElem('.groupMessages .direct-messages-list');
|
||||
if (isModalWithElemExists(elem))
|
||||
modalDMsSummaryDraw(elem, true);
|
||||
} else if ($.mobile.activePage.attr('id') !== 'directmsg')
|
||||
modalDMsSummaryDraw($('#directmsg .direct-messages-list'), true);
|
||||
}
|
||||
}
|
||||
|
||||
return newDMs;
|
||||
function getNewDMsCount() {
|
||||
var lengthNew = 0;
|
||||
|
||||
for (var peerAlias in twister.DMs)
|
||||
if (peerAlias[0] !== '*' && twister.DMs[peerAlias].lengthNew)
|
||||
lengthNew += twister.DMs[peerAlias].lengthNew;
|
||||
|
||||
return lengthNew;
|
||||
}
|
||||
|
||||
function getNewGroupDMsCount() {
|
||||
var newDMs = 0;
|
||||
var lengthNew = 0;
|
||||
|
||||
for (var user in _newDMsPerUser) {
|
||||
if (user[0] === '*' && _newDMsPerUser[user])
|
||||
newDMs += _newDMsPerUser[user];
|
||||
}
|
||||
for (var peerAlias in twister.DMs)
|
||||
if (peerAlias[0] === '*' && twister.DMs[peerAlias].lengthNew)
|
||||
lengthNew += twister.DMs[peerAlias].lengthNew;
|
||||
|
||||
return newDMs;
|
||||
return lengthNew;
|
||||
}
|
||||
|
||||
function resetNewDMsCountForUser(user, lastId) {
|
||||
_newDMsPerUser[user] = 0;
|
||||
_lastDMIdPerUser[user] = lastId;
|
||||
function resetNewDMsCount() {
|
||||
var isNewDetected;
|
||||
|
||||
for (var peerAlias in twister.DMs)
|
||||
if (twister.DMs[peerAlias].lengthNew && peerAlias[0] !== '*') {
|
||||
twister.DMs[peerAlias].lengthNew = 0;
|
||||
for (var j in twister.DMs[peerAlias].twists.cached)
|
||||
delete twister.DMs[peerAlias].twists.cached[j].isNew;
|
||||
|
||||
isNewDetected = true;
|
||||
}
|
||||
|
||||
if (!isNewDetected)
|
||||
return;
|
||||
|
||||
saveDMsToStorage();
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
}
|
||||
|
||||
function resetNewDMsCountGroup() {
|
||||
var isNewDetected;
|
||||
|
||||
for (var peerAlias in twister.DMs)
|
||||
if (twister.DMs[peerAlias].lengthNew && peerAlias[0] === '*') {
|
||||
twister.DMs[peerAlias].lengthNew = 0;
|
||||
for (var j in twister.DMs[peerAlias].twists.cached)
|
||||
delete twister.DMs[peerAlias].twists.cached[j].isNew;
|
||||
|
||||
isNewDetected = true;
|
||||
}
|
||||
|
||||
if (!isNewDetected)
|
||||
return;
|
||||
|
||||
saveDMsToStorage();
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
}
|
||||
|
||||
function resetNewDMsCountForPeer(peerAlias) {
|
||||
if (!twister.DMs[peerAlias].lengthNew)
|
||||
return;
|
||||
|
||||
twister.DMs[peerAlias].lengthNew = 0;
|
||||
for (var j in twister.DMs[peerAlias].twists.cached)
|
||||
delete twister.DMs[peerAlias].twists.cached[j].isNew;
|
||||
|
||||
saveDMsToStorage();
|
||||
if (peerAlias[0] !== '*')
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
else
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
}
|
||||
|
||||
function updateGroupList() {
|
||||
twisterRpc('listgroups', [],
|
||||
function(req, ret) {groupChatAliases = ret;}, null,
|
||||
@ -292,18 +483,58 @@ function updateGroupList() {
|
||||
}
|
||||
|
||||
function initDMsCount() {
|
||||
loadDMsFromStorage();
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
//quick hack to obtain list of group chat aliases
|
||||
updateGroupList();
|
||||
setInterval(updateGroupList, 60000);
|
||||
twister.DMs = {};
|
||||
dumpPrivkey(defaultScreenName, function (req, res) {
|
||||
twister.var.key = TwisterCrypto.PrivKey.fromWIF(res);
|
||||
|
||||
setTimeout(requestDMsCount, 200);
|
||||
//polling not needed: processNewPostsConfirmation will call requestDMsCount.
|
||||
//setInterval('requestDMsCount()', 5000);
|
||||
loadDMsFromStorage();
|
||||
$.MAL.updateNewDMsUI(getNewDMsCount());
|
||||
$.MAL.updateNewGroupDMsUI(getNewGroupDMsCount());
|
||||
//quick hack to obtain list of group chat aliases
|
||||
updateGroupList();
|
||||
setInterval(updateGroupList, 60000);
|
||||
|
||||
setTimeout(requestDMsCount, 200);
|
||||
//polling not needed: processNewPostsConfirmation will call requestDMsCount.
|
||||
//setInterval('requestDMsCount()', 5000);
|
||||
});
|
||||
}
|
||||
|
||||
function newmsgsChangedUser() {
|
||||
clearInterval(twister.mentions.interval);
|
||||
}
|
||||
|
||||
function handleDMsModalScroll(event) {
|
||||
if (!event || !event.data.req || !twister.DMs[event.data.req]
|
||||
|| twister.DMs[event.data.req].scrollQueryActive)
|
||||
return;
|
||||
|
||||
var length = twister.DMs[event.data.req].lastId - twister.DMs[event.data.req].lengthCached + 1;
|
||||
if (!length)
|
||||
return;
|
||||
|
||||
var elem = $(event.target);
|
||||
if (elem.scrollTop() < 100) {
|
||||
twister.DMs[event.data.req].scrollQueryActive = true;
|
||||
|
||||
twisterRpc('getdirectmsgs', [defaultScreenName, Math.min(length, postsPerRefresh),
|
||||
[{username: twister.DMs[event.data.req].query, max_id: length - 1}]],
|
||||
function (req, res) {
|
||||
twister.res[req.k].scrollQueryActive = false;
|
||||
//twister.res[req.k].boardAutoAppend = true; // FIXME all pending twists will be appended
|
||||
queryProcess(req.k, res);
|
||||
//twister.res[req.k].boardAutoAppend = false;
|
||||
if (req.container[0].scrollHeight !== req.containerScrollHeightPrev)
|
||||
req.container.scrollTop(req.container[0].scrollHeight - req.containerScrollHeightPrev);
|
||||
}, {
|
||||
k: twister.DMs[event.data.req].query + '@' + twister.DMs[event.data.req].resource,
|
||||
container: elem,
|
||||
containerScrollHeightPrev: elem[0].scrollHeight
|
||||
},
|
||||
function (req, res) {
|
||||
console.warn(polyglot.t('ajax_error',
|
||||
{error: (res && res.message) ? res.message : res}));
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -183,13 +183,18 @@ function processReceivedPosts(req, posts)
|
||||
}
|
||||
|
||||
function updateTimeline(req, posts) {
|
||||
attachPostsToStream($.MAL.getStreamPostsParent(), posts, req.getspam);
|
||||
attachPostsToStream($.MAL.getStreamPostsParent(), posts, true,
|
||||
function (twist, promoted) {
|
||||
return {item: postToElem(twist, 'original', promoted), time: twist.userpost.time};
|
||||
},
|
||||
req.getspam
|
||||
);
|
||||
for (var i = 0; i < posts.length; i++) {
|
||||
req.reportProcessedPost(posts[i]['userpost']['n'], posts[i]['userpost']['k'], true);
|
||||
}
|
||||
}
|
||||
|
||||
function attachPostsToStream(stream, posts, isPromoted) {
|
||||
function attachPostsToStream(stream, posts, descendingOrder, createElem, createElemReq) {
|
||||
//console.log('attachPostsToStream:');
|
||||
//console.log(posts);
|
||||
|
||||
@ -204,7 +209,7 @@ function attachPostsToStream(stream, posts, isPromoted) {
|
||||
for (var i = 0; i < posts.length; i++) {
|
||||
//console.log(posts[i]);
|
||||
var isAttached = false;
|
||||
var intrantPost = {item: postToElem(posts[i], 'original', isPromoted), time: posts[i].userpost.time};
|
||||
var intrantPost = createElem(posts[i], createElemReq);
|
||||
intrantPost.item.attr('data-time', intrantPost.time);
|
||||
|
||||
if (streamPosts.length) {
|
||||
@ -213,10 +218,10 @@ function attachPostsToStream(stream, posts, isPromoted) {
|
||||
if (intrantPost.time === streamPosts[j].time &&
|
||||
intrantPost.item[0].innerHTML === streamPosts[j].item[0].innerHTML) {
|
||||
isAttached = true;
|
||||
console.log('appending of duplicate twist prevented');
|
||||
console.warn('appending of duplicate twist prevented');
|
||||
break;
|
||||
} else if (intrantPost.time > streamPosts[j].time) {
|
||||
// this post in stream is older, so post must be inserted above
|
||||
} else if (descendingOrder ?
|
||||
intrantPost.time > streamPosts[j].time : intrantPost.time < streamPosts[j].time) {
|
||||
intrantPost.item.insertBefore(streamPosts[j].item).show();
|
||||
streamPosts.splice(j, 0, intrantPost);
|
||||
isAttached = true;
|
||||
|
38
options.html
38
options.html
@ -18,7 +18,6 @@
|
||||
<script src="js/twister_user.js"></script>
|
||||
<script src="js/twister_formatpost.js"></script>
|
||||
<script src="js/interface_common.js"></script>
|
||||
<script src="js/interface_login.js"></script>
|
||||
<script src="js/polyglot.min.js"></script>
|
||||
<script src="js/interface_localization.js"></script>
|
||||
|
||||
@ -53,6 +52,8 @@
|
||||
<label for="t-2" class="tabs selectable_theme theme_nin">Theme</label>
|
||||
<input id="t-3" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
|
||||
<label for="t-3" class="tabs selectable_theme theme_nin">Notifications</label>
|
||||
<input id="t-8" name="option_tab" type="radio" class="selectable_theme theme_nin" />
|
||||
<label for="t-8" class="tabs selectable_theme theme_nin">Direct Messages</label>
|
||||
<input id="t-4" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
|
||||
<label for="t-4" class="tabs selectable_theme theme_nin">Keys</label>
|
||||
<input id="t-5" name="option_tab" type="radio" class="selectable_theme theme_nin"/>
|
||||
@ -80,10 +81,12 @@
|
||||
<option value="de">German</option>
|
||||
<option value="it">Italian</option>
|
||||
<option value="ja">Japanese</option>
|
||||
<option value="cmn">Mandarin Chinese</option>
|
||||
<option value="ru">Russian</option>
|
||||
<option value="es">Spanish</option>
|
||||
<option value="tr">Turkish</option>
|
||||
<option value="uk">Ukrainian</option>
|
||||
<option value="yue">Yue Chinese</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
@ -195,6 +198,30 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="DMs">
|
||||
<div class="module">
|
||||
<p class="label label-h">Direct Messages</p>
|
||||
<div class="container">
|
||||
<form action="" id="dmCopySelfOpt">
|
||||
<p class="label">dm_copy_outgoing_to_self</p>
|
||||
<select name="" id="dmCopySelf" class="container">
|
||||
<option value="enable">Enable</option>
|
||||
<option value="disable">Disable</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
<div class="container">
|
||||
<form action="" id="dmEncryptCacheOpt">
|
||||
<p class="label">dm_encrypt_local_cache</p>
|
||||
<select name="" id="dmEncryptCache" class="container">
|
||||
<option value="enable">Enable</option>
|
||||
<option value="disable">Disable</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="keys">
|
||||
<div class="module">
|
||||
<p class="label label-h"> Keys </p>
|
||||
@ -458,15 +485,6 @@
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
<div class="container">
|
||||
<form action="" id="dmCopySelfOpt">
|
||||
<p class="label">Direct Message's copy to self</p>
|
||||
<select name="" id="dmCopySelf" class="container">
|
||||
<option value="disable">Disable</option>
|
||||
<option value="enable">Enable</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1415,7 +1415,7 @@ button:disabled:hover, button.disabled:hover, .mini-profile-actions span.disable
|
||||
visibility: hidden;
|
||||
}
|
||||
/* line 42, ../sass/_tabs.sass */
|
||||
.options input#tab_language:checked ~ .tab-content .language, .options input#t-2:checked ~ .tab-content .theme, .options input#t-3:checked ~ .tab-content .notifications, .options input#t-4:checked ~ .tab-content .keys, .options input#t-5:checked ~ .tab-content .appearance, .options input#t-6:checked ~ .tab-content .users, .options input#t-7:checked ~ .tab-content .webtorrent {
|
||||
.options input#tab_language:checked ~ .tab-content .language, .options input#t-2:checked ~ .tab-content .theme, .options input#t-3:checked ~ .tab-content .notifications, .options input#t-4:checked ~ .tab-content .keys, .options input#t-5:checked ~ .tab-content .appearance, .options input#t-6:checked ~ .tab-content .users, .options input#t-7:checked ~ .tab-content .webtorrent, .options input#t-8:checked ~ .tab-content .DMs {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
opacity: 1;
|
||||
|
@ -53,12 +53,8 @@ $(function(){
|
||||
});
|
||||
|
||||
function localizeLabels() {
|
||||
$("label[for=tab_language]").text(polyglot.t("Language"));
|
||||
$("label[for=t-2]").text(polyglot.t("Theme"));
|
||||
$("label[for=t-3]").text(polyglot.t("Notifications"));
|
||||
$("label[for=t-4]").text(polyglot.t("Keys"));
|
||||
$("label[for=t-5]").text(polyglot.t("Appearance"));
|
||||
$("label[for=t-6]").text(polyglot.t("Users"));
|
||||
$("label[for=t-7]").text(polyglot.t("WebTorrent"));
|
||||
$('label.tabs').each(function (i, elem) {
|
||||
var elem = $(elem);
|
||||
elem.text(polyglot.t(elem.text()));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
&#t-5:checked ~ .tab-content .appearance,
|
||||
&#t-6:checked ~ .tab-content .users
|
||||
&#t-7:checked ~ .tab-content .webtorrent
|
||||
&#t-8:checked ~ .tab-content .DMs
|
||||
position: relative
|
||||
z-index: 10
|
||||
opacity: 1
|
||||
@ -59,7 +60,7 @@
|
||||
text-align: center
|
||||
width: auto
|
||||
display: inline-block!important
|
||||
margin: 0 5px 0 0
|
||||
margin: 0 5px 0 0
|
||||
padding: 5px 15px
|
||||
color: $main-color-light
|
||||
background: $background-light
|
||||
@ -67,5 +68,3 @@
|
||||
input:checked + label.tabs
|
||||
background: $bloc-background-color
|
||||
color: $main-color-dark
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user