]> Untitled Git - lemmy.git/commitdiff
Merge branch 'dev' into federation
authorDessalines <tyhou13@gmx.com>
Tue, 14 Apr 2020 20:07:20 +0000 (16:07 -0400)
committerDessalines <tyhou13@gmx.com>
Tue, 14 Apr 2020 20:07:20 +0000 (16:07 -0400)
18 files changed:
1  2 
server/src/api/site.rs
server/src/lib.rs
server/src/main.rs
server/src/settings.rs
server/src/websocket/server.rs
ui/package.json
ui/src/components/comment-form.tsx
ui/src/components/comment-node.tsx
ui/src/components/navbar.tsx
ui/src/components/post-form.tsx
ui/src/components/post-listing.tsx
ui/src/components/post.tsx
ui/src/components/private-message-form.tsx
ui/src/components/private-message.tsx
ui/src/components/sidebar.tsx
ui/src/interfaces.ts
ui/src/utils.ts
ui/yarn.lock

Simple merge
Simple merge
index 59dc2cb7572428c8d353ade1d78fc8ff1e4c8cef,f3887527571a43b7424295a5d599dff3eb26bd74..88d62eb997c9fd374a4a1fc3661257d1f64029a0
@@@ -55,32 -38,31 +55,33 @@@ async fn main() -> Result<(), Error> 
    );
  
    // Create Http server with websocket support
 -  HttpServer::new(move || {
 -    let settings = Settings::get();
 -    App::new()
 -      .wrap(middleware::Logger::default())
 -      .data(pool.clone())
 -      .data(server.clone())
 -      // The routes
 -      .configure(api::config)
 -      .configure(federation::config)
 -      .configure(feeds::config)
 -      .configure(index::config)
 -      .configure(nodeinfo::config)
 -      .configure(webfinger::config)
 -      .configure(websocket::config)
 -      // static files
 -      .service(actix_files::Files::new(
 -        "/static",
 -        settings.front_end_dir.to_owned(),
 -      ))
 -      .service(actix_files::Files::new(
 -        "/docs",
 -        settings.front_end_dir + "/documentation",
 -      ))
 -  })
 -  .bind((settings.bind, settings.port))?
 -  .run()
 -  .await
 +  Ok(
 +    HttpServer::new(move || {
++      let settings = Settings::get();
 +      App::new()
 +        .wrap(middleware::Logger::default())
 +        .data(pool.clone())
 +        .data(server.clone())
 +        // The routes
 +        .configure(api::config)
 +        .configure(federation::config)
 +        .configure(feeds::config)
 +        .configure(index::config)
 +        .configure(nodeinfo::config)
 +        .configure(webfinger::config)
 +        .configure(websocket::config)
 +        // static files
 +        .service(actix_files::Files::new(
 +          "/static",
 +          settings.front_end_dir.to_owned(),
 +        ))
 +        .service(actix_files::Files::new(
 +          "/docs",
 +          settings.front_end_dir.to_owned() + "/documentation",
 +        ))
 +    })
 +    .bind((settings.bind, settings.port))?
 +    .run()
 +    .await?,
 +  )
  }
index 29d5966bafc173fbf4dfa32db844a6181fffcc02,6e5667cb2ee7fbc56a9a8394c3aedae18f07efa9..8c3cd6a1251d035b7220a43f5e7440e266220767
@@@ -17,10 -20,10 +20,10 @@@ pub struct Settings 
    pub front_end_dir: String,
    pub rate_limit: RateLimitConfig,
    pub email: Option<EmailConfig>,
 -  pub federation_enabled: bool,
 +  pub federation: Federation,
  }
  
- #[derive(Debug, Deserialize)]
+ #[derive(Debug, Deserialize, Clone)]
  pub struct Setup {
    pub admin_username: String,
    pub admin_password: String,
@@@ -57,20 -60,11 +60,18 @@@ pub struct Database 
    pub pool_size: u32,
  }
  
 +#[derive(Debug, Deserialize)]
 +pub struct Federation {
 +  pub enabled: bool,
 +  pub followed_instances: String,
 +  pub tls_enabled: bool,
 +}
 +
  lazy_static! {
-   static ref SETTINGS: Settings = {
-     match Settings::init() {
-       Ok(c) => c,
-       Err(e) => panic!("{}", e),
-     }
-   };
+   static ref SETTINGS: RwLock<Settings> = RwLock::new(match Settings::init() {
+     Ok(c) => c,
+     Err(e) => panic!("{}", e),
+   });
  }
  
  impl Settings {
Simple merge
diff --cc ui/package.json
index 7d946614c887d2bdb0213bb2c9c8b9ded46eff45,21458f0d2f20563e94f9467da69f25e3f0f3dc26..d2eb1de9ebd859e7590234d04439f272b44ae74f
    },
    "keywords": [],
    "dependencies": {
+     "@joeattardi/emoji-button": "^2.12.1",
      "@types/autosize": "^3.0.6",
-     "@types/js-cookie": "^2.2.5",
+     "@types/js-cookie": "^2.2.6",
      "@types/jwt-decode": "^2.2.1",
 -    "@types/markdown-it": "^10.0.0",
 +    "@types/markdown-it": "^0.0.9",
      "@types/markdown-it-container": "^2.0.2",
-     "@types/node": "^13.9.2",
+     "@types/node": "^13.11.1",
      "autosize": "^4.0.2",
      "bootswatch": "^4.3.1",
-     "classcat": "^1.1.3",
+     "classcat": "^4.0.2",
      "dotenv": "^8.2.0",
      "emoji-short-name": "^1.0.0",
-     "husky": "^4.2.3",
-     "i18next": "^19.3.3",
+     "husky": "^4.2.5",
+     "i18next": "^19.4.1",
      "inferno": "^7.4.2",
      "inferno-i18next": "nimbusec-oss/inferno-i18next",
      "inferno-router": "^7.4.2",
index ae3e7cfc3ff964b7b112f475c9f1c5a0544b08a1,5239eb2c7a10660182154a1dd7f91b305ca367b7..b3c1a9a164fe093191dc8aa17ee4f401c19b5be5
@@@ -158,8 -162,8 +162,9 @@@ export class CommentForm extends Compon
                </button>
                {this.state.commentForm.content && (
                  <button
--                  className={`btn btn-sm mr-2 btn-secondary ${this.state
--                    .previewMode && 'active'}`}
++                  className={`btn btn-sm mr-2 btn-secondary ${
++                    this.state.previewMode && 'active'
++                  }`}
                    onClick={linkEvent(this, this.handlePreviewToggle)}
                  >
                    {i18n.t('preview')}
index 39f29b5f84eab110dc4bd7ca37f9915e7b923cdb,ba4301e169a0475d9c69c6a9b71b48d4a7b01216..69a78f5015a4b0a5db4c0e7ecb0e5693a4a66818
@@@ -143,25 -142,19 +142,21 @@@ export class CommentNode extends Compon
            }
          >
            <div
--            class={`${!this.props.noIndent &&
++            class={`${
++              !this.props.noIndent &&
                this.props.node.comment.parent_id &&
--              'ml-2'}`}
++              'ml-2'
++            }`}
            >
              <div class="d-flex flex-wrap align-items-center mb-1 mt-1 text-muted small">
-               <Link
-                 className="mr-2 text-body font-weight-bold"
-                 to={`/u/${node.comment.creator_name}`}
-               >
-                 {node.comment.creator_avatar && showAvatars() && (
-                   <img
-                     height="32"
-                     width="32"
-                     src={pictshareAvatarThumbnail(node.comment.creator_avatar)}
-                     class="rounded-circle mr-1"
-                   />
-                 )}
-                 <span>{node.comment.creator_name}</span>
-               </Link>
+               <span class="mr-2">
+                 <UserListing
+                   user={{
+                     name: node.comment.creator_name,
+                     avatar: node.comment.creator_avatar,
+                   }}
+                 />
+               </span>
                {this.isMod && (
                  <div className="badge badge-light d-none d-sm-inline mr-2">
                    {i18n.t('mod')}
                          this.loadingIcon
                        ) : (
                          <svg
--                          class={`icon icon-inline ${node.comment.read &&
--                            'text-success'}`}
++                          class={`icon icon-inline ${
++                            node.comment.read && 'text-success'
++                          }`}
                          >
                            <use xlinkHref="#icon-check"></use>
                          </svg>
                            this.loadingIcon
                          ) : (
                            <svg
--                            class={`icon icon-inline ${node.comment.saved &&
--                              'text-warning'}`}
++                            class={`icon icon-inline ${
++                              node.comment.saved && 'text-warning'
++                            }`}
                            >
                              <use xlinkHref="#icon-star"></use>
                            </svg>
                              data-tippy-content={i18n.t('view_source')}
                            >
                              <svg
--                              class={`icon icon-inline ${this.state
--                                .viewSource && 'text-success'}`}
++                              class={`icon icon-inline ${
++                                this.state.viewSource && 'text-success'
++                              }`}
                              >
                                <use xlinkHref="#icon-file-text"></use>
                              </svg>
                                  }
                                >
                                  <svg
--                                  class={`icon icon-inline ${node.comment
--                                    .deleted && 'text-danger'}`}
++                                  class={`icon icon-inline ${
++                                    node.comment.deleted && 'text-danger'
++                                  }`}
                                  >
                                    <use xlinkHref="#icon-trash"></use>
                                  </svg>
index d7f3b5a8a1163ec1663f681e74b5cc59c8cc9881,e0d8aff50ad98789073adc97bad7a170638787d9..f1936be1812fcd01af3898889821d8192540b14d
@@@ -353,9 -372,16 +372,16 @@@ export class Navbar extends Component<a
      );
    }
  
+   get canAdmin(): boolean {
+     return (
+       UserService.Instance.user &&
+       this.state.admins.map(a => a.id).includes(UserService.Instance.user.id)
+     );
+   }
    requestNotificationPermission() {
      if (UserService.Instance.user) {
--      document.addEventListener('DOMContentLoaded', function() {
++      document.addEventListener('DOMContentLoaded', function () {
          if (!Notification) {
            toast(i18n.t('notifications_error'), 'danger');
            return;
index 47920b9b4ecfb2a9051dce01c4bdf6b76e93c14f,912d8e5896157c89ae6e9be9925b08b10b2849c0..4dbc8b23a314b3d7bdd3d3e538f659b3ecbba9c8
@@@ -190,8 -194,8 +194,9 @@@ export class PostForm extends Component
                <form>
                  <label
                    htmlFor="file-upload"
--                  className={`${UserService.Instance.user &&
-                     'pointer'} d-inline-block float-right text-muted h6 font-weight-bold`}
 -                    'pointer'} d-inline-block float-right text-muted font-weight-bold`}
++                  className={`${
++                    UserService.Instance.user && 'pointer'
++                  } d-inline-block float-right text-muted font-weight-bold`}
                    data-tippy-content={i18n.t('upload_image')}
                  >
                    <svg class="icon icon-inline">
                )}
                {this.state.postForm.body && (
                  <button
--                  className={`mt-1 mr-2 btn btn-sm btn-secondary ${this.state
--                    .previewMode && 'active'}`}
++                  className={`mt-1 mr-2 btn btn-sm btn-secondary ${
++                    this.state.previewMode && 'active'
++                  }`}
                    onClick={linkEvent(this, this.handlePreviewToggle)}
                  >
                    {i18n.t('preview')}
index 49970dfc195c34a86018dca3ff5d6311598d9a70,d0efa0437225e298c1b382071ea7521a85d7bc6a..497492010690049c18bc6b37156d558c32584821
@@@ -26,11 -28,9 +28,10 @@@ import 
    isImage,
    isVideo,
    getUnixTime,
-   pictshareAvatarThumbnail,
-   showAvatars,
    pictshareImage,
    setupTippy,
 +  hostname,
+   previewLines,
  } from '../utils';
  import { i18n } from '../i18next';
  
index f51ba6ff91c62b6ef24578c22ded673360b28637,de0f0e329c72bf60d24a7de43e2fcfaa89a427f1..cf9e748652e5241ddcaf9ba84f64da0d4f259ba4
@@@ -213,8 -213,8 +213,9 @@@ export class Post extends Component<any
      return (
        <div class="btn-group btn-group-toggle mb-2">
          <label
--          className={`btn btn-sm btn-secondary pointer ${this.state
--            .commentSort === CommentSortType.Hot && 'active'}`}
++          className={`btn btn-sm btn-secondary pointer ${
++            this.state.commentSort === CommentSortType.Hot && 'active'
++          }`}
          >
            {i18n.t('hot')}
            <input
            />
          </label>
          <label
--          className={`btn btn-sm btn-secondary pointer ${this.state
--            .commentSort === CommentSortType.Top && 'active'}`}
++          className={`btn btn-sm btn-secondary pointer ${
++            this.state.commentSort === CommentSortType.Top && 'active'
++          }`}
          >
            {i18n.t('top')}
            <input
            />
          </label>
          <label
--          className={`btn btn-sm btn-secondary pointer ${this.state
--            .commentSort === CommentSortType.New && 'active'}`}
++          className={`btn btn-sm btn-secondary pointer ${
++            this.state.commentSort === CommentSortType.New && 'active'
++          }`}
          >
            {i18n.t('new')}
            <input
            />
          </label>
          <label
--          className={`btn btn-sm btn-secondary pointer ${this.state
--            .commentSort === CommentSortType.Old && 'active'}`}
++          className={`btn btn-sm btn-secondary pointer ${
++            this.state.commentSort === CommentSortType.Old && 'active'
++          }`}
          >
            {i18n.t('old')}
            <input
index 7e498bae3ca9048ac9f5855591556fd713f6ca13,6b607654b62b943ae4e3a9e71da7d6a2f9ee4e0d..14abacf62086ca1e0fccab3a49275eabdf11bc4b
@@@ -233,8 -222,8 +222,9 @@@ export class PrivateMessageForm extend
                </button>
                {this.state.privateMessageForm.content && (
                  <button
--                  className={`btn btn-secondary mr-2 ${this.state.previewMode &&
--                    'active'}`}
++                  className={`btn btn-secondary mr-2 ${
++                    this.state.previewMode && 'active'
++                  }`}
                    onClick={linkEvent(this, this.handlePreviewToggle)}
                  >
                    {i18n.t('preview')}
index ef128dd4a813329047d4580a217a1042c59412ff,337b165012000f5598dcdd6ff4d670703aec765f..3acd6e19f06c1c40d2171866ee1f63d4830e38d4
@@@ -143,8 -144,8 +144,9 @@@ export class PrivateMessage extends Com
                          }
                        >
                          <svg
--                          class={`icon icon-inline ${message.read &&
--                            'text-success'}`}
++                          class={`icon icon-inline ${
++                            message.read && 'text-success'
++                          }`}
                          >
                            <use xlinkHref="#icon-check"></use>
                          </svg>
                          }
                        >
                          <svg
--                          class={`icon icon-inline ${message.deleted &&
--                            'text-danger'}`}
++                          class={`icon icon-inline ${
++                            message.deleted && 'text-danger'
++                          }`}
                          >
                            <use xlinkHref="#icon-trash"></use>
                          </svg>
                      data-tippy-content={i18n.t('view_source')}
                    >
                      <svg
--                      class={`icon icon-inline ${this.state.viewSource &&
--                        'text-success'}`}
++                      class={`icon icon-inline ${
++                        this.state.viewSource && 'text-success'
++                      }`}
                      >
                        <use xlinkHref="#icon-file-text"></use>
                      </svg>
index 0f4a0e10d8f262cdbd900b43a96b9a4a27bdaa02,d66266f6cab0e0e5a0769d8aa381d0c3ba6cb618..4b317aaa29880c957072d38945e019279658eb5c
@@@ -110,8 -111,8 +111,9 @@@ export class Sidebar extends Component<
                          }
                        >
                          <svg
--                          class={`icon icon-inline ${community.deleted &&
--                            'text-danger'}`}
++                          class={`icon icon-inline ${
++                            community.deleted && 'text-danger'
++                          }`}
                          >
                            <use xlinkHref="#icon-trash"></use>
                          </svg>
                ))}
              </ul>
              <Link
--              class={`btn btn-sm btn-secondary btn-block mb-3 ${(community.deleted ||
--                community.removed) &&
--                'no-click'}`}
++              class={`btn btn-sm btn-secondary btn-block mb-3 ${
++                (community.deleted || community.removed) && 'no-click'
++              }`}
                to={`/create_post?community=${community.name}`}
              >
                {i18n.t('create_a_post')}
Simple merge
diff --cc ui/src/utils.ts
index e2310960d1ac489dedaae11d438c0cc3b9de4ec1,21a7fef83e83987fb5101d8b1531a5e8ff9bc5a9..480b41c7c313a6ffcd6403456583b4ee14fe2ee9
@@@ -824,6 -834,10 +834,14 @@@ function randomHsl() 
    return `hsla(${Math.random() * 360}, 100%, 50%, 1)`;
  }
  
+ export function previewLines(text: string, lines: number = 3): string {
+   // Use lines * 2 because markdown requires 2 lines
+   return text
+     .split('\n')
+     .slice(0, lines * 2)
+     .join('\n');
+ }
++
 +export function hostname(url: string): string {
 +  return new URL(url).hostname;
 +}
diff --cc ui/yarn.lock
index 8d75052b905f12eb017da5a55457a6646e6f6657,35ad32a0ac2ea8390e621ed82083676bca5d49c0..4e94559eed7716121ba0f8da0b8e59849f4dadbd
    dependencies:
      "@types/linkify-it" "*"
  
- "@types/node@^13.9.2":
-   version "13.9.2"
-   resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349"
-   integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg==
 -"@types/markdown-it@^10.0.0":
 -  version "10.0.0"
 -  resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-10.0.0.tgz#a2b5f9fb444bb27c1e0c4a0116fea09b3c6ebc1e"
 -  integrity sha512-7UPBg1W0rfsqQ1JwNFfhxibKO0t7Q0scNt96XcFIFLGE/vhZamzZayaFS2LKha/26Pz7b/2GgiaxQZ1GUwW0dA==
 -  dependencies:
 -    "@types/linkify-it" "*"
 -    "@types/mdurl" "*"
 -
 -"@types/mdurl@*":
 -  version "1.0.2"
 -  resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9"
 -  integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==
 -
+ "@types/node@^13.11.1":
+   version "13.11.1"
+   resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
+   integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
  
  "@types/normalize-package-data@^2.4.0":
    version "2.4.0"