|
|
- <!DOCTYPE html>
- <html lang="zh-CN">
-
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
- <link rel="icon" type="image/png" href="/img/ord/icon-128.png" />
- <meta property="og:title" content="闭社简化版" />
- <meta property="og:description" content="一个提供更简洁界面的闭社web client" />
- <link href="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
- <title>闭社简化版</title>
- <style>
- body {
- background: linear-gradient(-45deg, #fff calc(50% - 1px), #d0d0d0 calc(50%), #fff calc(50% + 1px) );
- background-size: 6px 5px;
- font-family: 'Noto Sans SC', sans-serif;
- }
-
- body.grey {
- background: #707070;
- background-size: 6px 5px;
- }
-
- body,
- pre {
- font-family: 'Noto Sans SC', sans-serif;
- }
-
- h1,
- h2,
- h3,
- h4,
- h5,
- h6 {
- font-family: 'Noto Serif SC', serif;
- font-weight: 300;
- }
-
- a,
- a:hover,
- .btn-link,
- .btn-link:hover {
- color: inherit;
- text-decoration: underline;
- display: inline-block;
- }
-
- .part1 {
- min-width: 300px;
- float: left;
- padding-right: 10px;
- position: relative;
- }
-
- .part2 {
- min-width: 200px;
- overflow: hidden;
- padding-left: 25px;
- }
-
- .qbox {
- border: 2px black solid;
- background: white;
- padding: 5px;
- color: black;
- margin: 5px 5px 20px;
- }
-
- body.grey #statuses-list .qbox {
- background: #b0b0b0;
- }
-
- .new .qbox {
- background: black;
- color: white;
- }
-
- .new .qbox textarea {
- background: black;
- color: white;
- }
-
- .qbox textarea {
- border: none;
- border-bottom: 1px solid;
- border-radius: 0;
- }
-
- body.grey #statuses-list .qbox textarea {
- background: #b0b0b0;
- }
-
- .qbox .content {
- margin: 15px 5px;
- }
-
- .liked, .reblogged {
- font-weight: bold;
- }
-
- .timeago {
- font-size: 0.5em;
- }
-
- .display_name {
- margin: 0;
- }
-
- .behind {
- z-index: 98;
- cursor: pointer;
- transform: translateY(5px) scale(0.98);
- transform-origin: top;
- transition-property: transform;
- transition-duration: 0.5s;
- }
-
- .front {
- z-index: 99;
- transition-property: transform;
- transition-duration: 0.5s;
- }
-
- .judge {
- position: absolute;
- top: 0;
- right: 0;
- margin: 0 0 30px 20px;
- width: 90%;
- }
- .new {
- position: relative;
- margin: 30px 20px 30px 0;
- }
-
- a.hashtag {
- font-weight: bold;
- }
-
- .comment-list-wrapper {
- background: #3333;
- padding-left: 7%;
- font-size: 90%;
- }
-
- .status-media {
- max-height: 500px;
- max-width: 100%;
- margin: 10px auto;
- }
-
- .emoji {
- width: 22px;
- vertical-align: text-bottom;
- }
- #statuses-list .invisible {
- font-size: 0;
- line-height: 0;
- display: inline-block;
- width: 0;
- height: 0;
- visibility: visible !important;
- }
-
- #statuses-list .ellipsis::after {
- content: "...";
- }
- </style>
- </head>
-
- <body>
- <div class="container" style="overflow: hidden;min-height: 100vh">
- <div style='padding:15px'>
- <h1> 闭社简化版 </h1>
- </div>
-
-
- <div class="part1">
-
- <div class="new">
- <form action="" onsubmit="return post_status(event, '')">
- <div class="form-group qbox">
- <textarea class="form-control" name="text" rows="5" maxlength="5000" placeholder="啥?" required="required"></textarea>
- <div class="form-check mt-3 mb-3">
- <input class="form-check-input" type="checkbox" value="" id="post-checkbox-an">
- <label class="form-check-label" for="post-checkbox-an">
- 匿名
- </label>
- </div>
- <button type="submit" class="btn btn-link btn-lg">发布</button>
- </div>
- </form>
- </div>
- </div>
-
- <div class="part2" id="part2">
- <h1>本站</h1>
- <button class="btn btn-link grey_theme">切换亮度</button>
- <div id="statuses-list">
- </div>
- <span id="loading-span">加载中..</span>
- </div>
-
- </div>
- </body>
-
- <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
- <script src="https://cdn.bootcss.com/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery-timeago/1.6.7/jquery.timeago.min.js"></script>
- <script src="https://cdn.bootcdn.net/ajax/libs/jquery-timeago/1.6.7/locales/jquery.timeago.zh-CN.js"></script>
-
- <script>
- var token;
- var max_id;
- var loading_statues;
- var base_api_url = "https://thu.closed.social/";
-
- function get_token() {
- (document.cookie || "").split("; ").forEach( (c) => {
- let cc = c.split("=");
- if (cc.shift() === "mast_token") {
- token = cc.join("=");
- }
- });
- }
-
- function get_more_statuses() {
- loading_statues = true;
- $.getJSON(
- `${base_api_url}api/v1/timelines/public?limit=20&local=true` + (
- max_id ? `&max_id=${max_id}` : ''
- ),
- function (data) {
- data.forEach((status) => {
- $('#statuses-list').append(make_status_box_html(status, true));
- });
- $('.timeago').timeago();
- if (data.length) {
- max_id = data[data.length - 1].id;
- loading_statues = false;
- }
- }
- ).fail((e) => {
- alert(e.responseText);
- });
- }
-
-
- function render_content(text, is_mask_bot, emojis) {
- if (is_mask_bot) {
- text = text.replace(/^<p>\[([^\]]*)\]:<br \/>/, '<p>').replace(/匿了<\/p>$/, '</p>');
- }
- emojis.forEach((emoji) => {
- text = text.replaceAll(`:${emoji.shortcode}:`, `<img class="emoji" src="${emoji.url}">`);
- });
- return text;
- }
-
- function make_status_box_html(status) {
- return (`
- <div class="qbox" id="status-${status.id.toString()}">
- <img class="avatar" width="24" src="${status.account.avatar}">
- <small>
- ${status.account.acct === "mask_bot" ?
- "匿名用户" + /^<p>(\[[^\]]*\]):/.exec(status.content)[1] : (
- status.account.display_name + ' @' +status.account.acct)}
- </small>
- ${status.reblog && (status = status.reblog) &&
- `<small> 转发 @${status.account.acct}</small>` || ''}
- <div class="content">
- ${render_content(status.content, status.account.acct === "mask_bot", status.emojis)}
- </div>
- ${status.media_attachments.map((media) => {
- switch (media.type) {
- case 'image':
- return `<image class="status-media" src=${media.url}>`;
- case 'video':
- return `<video class="status-media" src=${media.url} controls></video>`;
- case 'gifv':
- return `<video class="status-media" src=${media.url} autoplay loop></video>`;
- default:
- return '';
- }
- }).join('\n')}
- <div style="text-align:right;margin: 0px 0 -5px">
- <time class="timeago mr-1" datetime="${status.created_at}"
- title="${status.created_at}"></time>
- <small class="mr-2">${status.application && status.application.name || ''}</small>
- <a href="###" class="mr-3 like-btn ${status.favourited? 'liked' : ''}"
- onclick="like_status(event, '${status.id.toString()}')">
- 点赞<span class="num">${status.favourites_count}</span>
- </a>
- <a href="###" class="mr-3 reblog-btn ${status.reblogged? 'reblogged' : ''}"
- onclick="reblog_status(event, '${status.id.toString()}')">
- 转发<span class="num">${status.reblogs_count}</span>
- </a>
- <a class="mr-3 reply-btn" href="###"
- onclick="get_comments('${status.id.toString()}')">
- 回复${status.replies_count}
- </a>
- </div>
- <div class="collapse comment-list-wrapper" id="collapse-${status.id.toString()}">
- <div class="comment-list">
- </div>
- <form action="" onsubmit="return post_status(event, '${status.id}')">
- <div class="form-group qbox">
- <textarea class="form-control" rows="2" maxlength="5000" required="required" >@${status.account.acct} </textarea>
- <div class="form-check mt-1 mb-1">
- <input class="form-check-input" type="checkbox" value="" id="reply-${status.id}-checkbox-an">
- <label class="form-check-label" for="reply-${status.id}-checkbox-an">
- 匿名
- </label>
- </div>
- <button type="submit" class="btn btn-link">添加回复</button>
- </div>
- </form>
- </div>
- </div>
- `)
- }
-
- function get_comments(sid) {
- let coll = $(`#collapse-${sid}`);
- if (coll.hasClass('show')) {
- coll.collapse('hide');
- } else {
- coll.collapse('show');
- coll.find('> .comment-list').append("加载中..");
- $.getJSON(
- `${base_api_url}api/v1/statuses/${sid}/context`,
- function (data) {
- coll.find('> .comment-list').empty();
- data.descendants.forEach( (rp) => {
- let parent_coll = $(`#collapse-${rp.in_reply_to_id}`);
- parent_coll.collapse('show');
- parent_coll.find('> .comment-list').append(make_status_box_html(rp));
- });
- $('.timeago').timeago();
- }
- );
- }
- }
-
- function like_status(e, sid) {
- let target = $(e.target);
- if (!target.hasClass('liked')) {
- $.post(
- `${base_api_url}api/v1/statuses/${sid}/favourite`,
- (status) => {
- target.addClass('liked');
- target.find('.num').text(status.favourites_count)
- }
- );
- } else {
- $.post(
- `${base_api_url}api/v1/statuses/${sid}/unfavourite`,
- (status) => {
- target.removeClass('liked');
- target.find('.num').text(
- target.find('.num').text() - 1
- )
- }
- );
- }
- }
-
- function reblog_status(e, sid) {
- let target = $(e.target);
- if (!target.hasClass('reblogged')) {
- $.post(
- `${base_api_url}api/v1/statuses/${sid}/reblog`,
- (status) => {
- target.addClass('reblogged');
- target.find('.num').text(
- target.find('.num').text() - (-1)
- )
- }
- );
- } else {
- $.post(
- `${base_api_url}api/v1/statuses/${sid}/unreblog`,
- (status) => {
- target.removeClass('reblogged');
- target.find('.num').text(
- target.find('.num').text() - 1
- )
- }
- );
- }
- }
-
- function post_status(e, sid) {
- e.preventDefault();
- let form = $(e.target);
- let text = form.find('textarea').val();
- if (form.find('input[type=checkbox]').is(':checked')) {
- text += "\n匿了";
- }
- $.post(
- `${base_api_url}api/v1/statuses`,
- {'status': text, 'in_reply_to_id': sid || null, 'visibility': 'public'},
- (status) => {
- form.find('textarea').val('');
- if (sid) {
- form.prev().append(make_status_box_html(status));
- } else {
- $('#statuses-list').prepend(make_status_box_html(status));
- }
- },
- 'json'
- ).fail((e) => {
- alert(e.responseText);
- });
-
- return false;
- }
-
- $(document).ready(function(){
- get_token();
- console.log(token);
- if (!token) {
- location.href = `${base_api_url}oauth/authorize?client_id=Wjf6ajif5kl6rIIt_TLu7SAAluGskaQiTXZoIr44jUc&response_type=code&redirect_uri=${encodeURIComponent(location.origin + "/auth")}&scope=read+write&force_login=False`
- } else {
- $.ajaxSetup({
- headers : {
- 'Authorization' : 'Bearer ' + token
- }
- });
- get_more_statuses();
- $(window).scroll(() => {
- if($('#loading-span').offset().top < $(window).scrollTop() + $(window).innerHeight() * 1.5 && !loading_statues) {
- get_more_statuses();
- }
- });
- }
-
- $('.grey_theme').click((e) => {
- $('body').toggleClass("grey");
- });
- });
- </script>
-
- </html>
|