Running newer prettier.
}
.navbar-expand-lg .navbar-nav .nav-link {
- padding-right: .75rem !important;
- padding-left: .75rem !important;
+ padding-right: 0.75rem !important;
+ padding-left: 0.75rem !important;
}
.pointer {
}
.no-click {
- pointer-events:none;
+ pointer-events: none;
opacity: 0.65;
}
.upvote:hover {
- color: var(--info);
+ color: var(--info);
}
.upvote {
}
.md-div h1 {
- font-size:2rem;
+ font-size: 2rem;
}
.md-div h2 {
- font-size:1.8rem;
+ font-size: 1.8rem;
}
.md-div h3 {
- font-size:1.6rem;
+ font-size: 1.6rem;
}
.md-div h4 {
- font-size:1.4rem;
+ font-size: 1.4rem;
}
.md-div h5 {
- font-size:1.2rem;
+ font-size: 1.2rem;
}
.md-div table {
}
.post-title {
- line-height: 1.0;
+ line-height: 1;
}
.post-title a:visited {
}
@keyframes spins {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(359deg); }
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(359deg);
+ }
}
.dropdown-menu {
.text-wrap-truncate {
overflow: hidden;
- text-overflow: ellipsis
+ text-overflow: ellipsis;
}
#app {
top: 0;
right: 0;
padding: 2px;
- height: 1.5em;
+ height: 1.5em;
width: 1.5em;
- background: rgba(0,0,0,.4);
+ background: rgba(0, 0, 0, 0.4);
border-bottom-left-radius: 0.25rem !important;
border-top-right-radius: 0.25rem !important;
}
.link-overlay:hover {
- transition: .1s;
+ transition: 0.1s;
opacity: 1;
}
.link-overlay {
- transition: opacity .1s ease-in-out;
+ transition: opacity 0.1s ease-in-out;
position: absolute;
opacity: 0;
left: 0;
height: 100%;
width: 100%;
padding: 10px;
- background: rgba(0,0,0,.6);
+ background: rgba(0, 0, 0, 0.6);
}
-
+
.placeholder {
height: 50px;
width: 50px;
.show-input {
width: 13em !important;
-
}
.hide-input {
background: transparent !important;
width: 0px !important;
padding: 0 !important;
- }
+}
br.big {
display: block;
}
.avatar-overlay {
- width: 20%;
+ width: 20%;
height: 20%;
max-width: 120px;
max-height: 120px;
}
.img-icon {
- width: 2rem; height: 2rem;
+ width: 2rem;
+ height: 2rem;
}
.tribute-container ul {
margin-top: 2px;
padding: 0;
list-style: none;
-background: var(--light); }
+ background: var(--light);
+}
.tribute-container li {
padding: 5px 5px;
-cursor: pointer; }
+ cursor: pointer;
+}
.tribute-container li.highlight {
-background: var(--primary); }
+ background: var(--primary);
+}
.tribute-container li span {
-font-weight: bold; }
+ font-weight: bold;
+}
.tribute-container li.no-match {
-cursor: default; }
+ cursor: default;
+}
.tribute-container .menu-highlighted {
- font-weight: bold;
+ font-weight: bold;
}
// Variables
// --------------------------------------------------
-
//== Colors
//
//## Gray and brand colors for use across Bootstrap.
-//// colors from bs-2
+//// colors from bs-2
// Grays
// -------------------------
-$black: #000;
-$grayDark: #555;
-$gray: #bbb;
-$grayLight: #bbb;
-$white: #FFF;
-
+$black: #000;
+$grayDark: #555;
+$gray: #bbb;
+$grayLight: #bbb;
+$white: #fff;
// Accent colors
// -------------------------
-$blue: #5555Ff;
-$cyan: #55FFFF;
-$cyanDark: #00AAAA;
-$blueDark: #000084;
-$green: #55FF55;
-$greenDark: #00AA00;
-$magenta: #FF55FF;
-$magentaDark: #AA00AA;
-$red: #FF5555;
-$redDark: #AA0000;
-$yellow: #FEFE54;
-$brown: #AA5500;
-$orange: #A85400;
-$pink: #FE54FE;
-$purple: #FE5454;
+$blue: #5555ff;
+$cyan: #55ffff;
+$cyanDark: #00aaaa;
+$blueDark: #000084;
+$green: #55ff55;
+$greenDark: #00aa00;
+$magenta: #ff55ff;
+$magentaDark: #aa00aa;
+$red: #ff5555;
+$redDark: #aa0000;
+$yellow: #fefe54;
+$brown: #aa5500;
+$orange: #a85400;
+$pink: #fe54fe;
+$purple: #fe5454;
// end colors
-$gray-base: $gray;
-$gray-darker: $grayDark;
-$gray-dark: $grayDark;
-$gray-light: $grayLight;
-$gray-lighter: $grayLight;
-
-$brand-primary: $gray;
-$brand-primary-bg: $cyanDark;
-$brand-success: $greenDark;
-$brand-info: $brown;
-$brand-warning: $magentaDark;
-$brand-danger: $redDark;
+$gray-base: $gray;
+$gray-darker: $grayDark;
+$gray-dark: $grayDark;
+$gray-light: $grayLight;
+$gray-lighter: $grayLight;
+$brand-primary: $gray;
+$brand-primary-bg: $cyanDark;
+$brand-success: $greenDark;
+$brand-info: $brown;
+$brand-warning: $magentaDark;
+$brand-danger: $redDark;
//== Scaffolding
//
//## Settings for some of the most global styles.
//** Background color for `<body>`.
-$body-bg: $blueDark;
+$body-bg: $blueDark;
//** Global text color on `<body>`.
-$text-color: $gray-light;
+$text-color: $gray-light;
//** Global textual link color.
-$link-color: $brand-primary;
+$link-color: $brand-primary;
//** Link hover color set via `darken()` function.
-$link-hover-color: $white;
+$link-hover-color: $white;
//** Link hover decoration.
$link-hover-decoration: none;
-
//== Typography
//
//## Font, line-height, and color for body text, headings, and more.
-$font-family-sans-serif: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
-$font-family-serif: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
+$font-family-sans-serif: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
+$font-family-serif: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
//** Default monospace fonts for `<code>`, `<kbd>`, and `<pre>`.
-$font-family-monospace: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
-$font-family-base: $font-family-sans-serif;
+$font-family-monospace: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
+$font-family-base: $font-family-sans-serif;
-$baseWidth: 10px;
-$font-size-base: 18px;
-$font-size-large: $font-size-base;
-$font-size-small: $font-size-base;
+$baseWidth: 10px;
+$font-size-base: 18px;
+$font-size-large: $font-size-base;
+$font-size-small: $font-size-base;
-$font-size-h1: $font-size-base;
-$font-size-h2: $font-size-base;
-$font-size-h3: $font-size-base;
-$font-size-h4: $font-size-base;
-$font-size-h5: $font-size-base;
-$font-size-h6: $font-size-base;
+$font-size-h1: $font-size-base;
+$font-size-h2: $font-size-base;
+$font-size-h3: $font-size-base;
+$font-size-h4: $font-size-base;
+$font-size-h5: $font-size-base;
+$font-size-h6: $font-size-base;
//** Unit-less `line-height` for use in components like buttons.
-$baseLineHeight: 19px;
-$line-height-base: $baseLineHeight;
+$baseLineHeight: 19px;
+$line-height-base: $baseLineHeight;
//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-$line-height-computed: $line-height-base;
+$line-height-computed: $line-height-base;
//** By default, this inherits from the `<body>`.
-$headings-font-family: inherit;
-$headings-font-weight: normal;
-$headings-line-height: $line-height-base;
-$headings-color: inherit;
-
-$space: $baseWidth;
-$halfbaseLineHeight: ($baseLineHeight / 2);
-$borderWidth: 2px;
-$baseLineWidth: ($baseLineHeight / 2);
-$halfSpace: ($baseWidth / 2);
-$lhsNB: ($baseWidth / 2 + 1);
-$rhsNB: ($baseWidth / 2 - 1);
-$lhs: ($lhsNB - ($borderWidth));
-$rhs: ($rhsNB - ($borderWidth / 2));
-$tsNB: ($baseLineHeight / 2);
-$bsNB: $tsNB;
-$ts: ($tsNB - ($borderWidth / 2));
-$bs: $ts;
-$tsMargin: 3px;
-
+$headings-font-family: inherit;
+$headings-font-weight: normal;
+$headings-line-height: $line-height-base;
+$headings-color: inherit;
+
+$space: $baseWidth;
+$halfbaseLineHeight: ($baseLineHeight / 2);
+$borderWidth: 2px;
+$baseLineWidth: ($baseLineHeight / 2);
+$halfSpace: ($baseWidth / 2);
+$lhsNB: ($baseWidth / 2 + 1);
+$rhsNB: ($baseWidth / 2 - 1);
+$lhs: ($lhsNB - ($borderWidth));
+$rhs: ($rhsNB - ($borderWidth / 2));
+$tsNB: ($baseLineHeight / 2);
+$bsNB: $tsNB;
+$ts: ($tsNB - ($borderWidth / 2));
+$bs: $ts;
+$tsMargin: 3px;
//== Iconography
//
//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via Bower.
//** Load fonts from this directory.
-$icon-font-path: "../fonts/";
+$icon-font-path: "../fonts/";
//** File name for all font files.
-$icon-font-name: "glyphicons-halflings-regular";
+$icon-font-name: "glyphicons-halflings-regular";
//** Element ID within SVG icon file.
-$icon-font-svg-id: "glyphicons_halflingsregular";
-
+$icon-font-svg-id: "glyphicons_halflingsregular";
//== Components
//
//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-$padding-base-vertical: 0px;
-$padding-base-horizontal: 0px;
+$padding-base-vertical: 0px;
+$padding-base-horizontal: 0px;
-$padding-large-vertical: 0px;
-$padding-large-horizontal: $halfSpace;
+$padding-large-vertical: 0px;
+$padding-large-horizontal: $halfSpace;
-$padding-small-vertical: 0px;
-$padding-small-horizontal: 0px;
+$padding-small-vertical: 0px;
+$padding-small-horizontal: 0px;
-$padding-xs-vertical: 0px;
-$padding-xs-horizontal: 0px;
+$padding-xs-vertical: 0px;
+$padding-xs-horizontal: 0px;
-$line-height-large: $baseLineHeight;
-$line-height-small: $baseLineHeight;
+$line-height-large: $baseLineHeight;
+$line-height-small: $baseLineHeight;
-$border-radius-base: 0;
-$border-radius-large: 0;
-$border-radius-small: 0;
+$border-radius-base: 0;
+$border-radius-large: 0;
+$border-radius-small: 0;
//** Global color for active items (e.g., navs or dropdowns).
-$component-active-color: $white;
+$component-active-color: $white;
//** Global background color for active items (e.g., navs or dropdowns).
-$component-active-bg: $black;
+$component-active-bg: $black;
//** Width of the `border` for generating carets that indicator dropdowns.
-$caret-width-base: 4px;
+$caret-width-base: 4px;
//** Carets increase slightly in size for larger components.
-$caret-width-large: 5px;
-
+$caret-width-large: 5px;
//== Tables
//
//## Customizes the `.table` component with basic values, each used across all table variations.
//** Padding for `<th>`s and `<td>`s.
-$table-cell-padding: $ts $rhs $bs $lhs;
+$table-cell-padding: $ts $rhs $bs $lhs;
//** Padding for cells in `.table-condensed`.
-$table-condensed-cell-padding: $ts $rhs $bs $lhs;
+$table-condensed-cell-padding: $ts $rhs $bs $lhs;
//** Default background color used for all tables.
-$table-bg: transparent;
+$table-bg: transparent;
//** Background color used for `.table-striped`.
-$table-bg-accent: $black;
+$table-bg-accent: $black;
//** Background color used for `.table-hover`.
-$table-bg-hover: #f5f5f5;
-$table-bg-active: $table-bg-hover;
+$table-bg-hover: #f5f5f5;
+$table-bg-active: $table-bg-hover;
//** Border color for table and cell borders.
-$table-border-color: $gray;
-
+$table-border-color: $gray;
//== Buttons
//
//## For each of Bootstrap's buttons, define text, background and border color.
-$btn-font-weight: normal;
+$btn-font-weight: normal;
-$btn-default-color: $black;
-$btn-default-bg: $grayLight;
-$btn-default-border: $grayLight;
+$btn-default-color: $black;
+$btn-default-bg: $grayLight;
+$btn-default-border: $grayLight;
-$btn-primary-color: $black;
-$btn-primary-bg: $cyanDark;
-$btn-primary-border: $grayLight;
+$btn-primary-color: $black;
+$btn-primary-bg: $cyanDark;
+$btn-primary-border: $grayLight;
-$btn-success-color: #fff;
-$btn-success-bg: $brand-success;
-$btn-success-border: $btn-success-bg;
+$btn-success-color: #fff;
+$btn-success-bg: $brand-success;
+$btn-success-border: $btn-success-bg;
-$btn-info-color: #fff;
-$btn-info-bg: $brand-info;
-$btn-info-border: $btn-info-bg;
+$btn-info-color: #fff;
+$btn-info-bg: $brand-info;
+$btn-info-border: $btn-info-bg;
-$btn-warning-color: #fff;
-$btn-warning-bg: $brand-warning;
-$btn-warning-border: $btn-warning-bg;
+$btn-warning-color: #fff;
+$btn-warning-bg: $brand-warning;
+$btn-warning-border: $btn-warning-bg;
-$btn-danger-color: #fff;
-$btn-danger-bg: $brand-danger;
-$btn-danger-border: $btn-danger-bg;
-
-$btn-link-disabled-color: $gray-light;
+$btn-danger-color: #fff;
+$btn-danger-bg: $brand-danger;
+$btn-danger-border: $btn-danger-bg;
+$btn-link-disabled-color: $gray-light;
//== Forms
//
//##
//** `<input>` background color
-$input-bg: $cyanDark;
+$input-bg: $cyanDark;
//** `<input disabled>` background color
-$input-bg-disabled: $gray-lighter;
+$input-bg-disabled: $gray-lighter;
//** Text color for `<input>`s
-$input-color: $white;
+$input-color: $white;
//** `<input>` border color
-$input-border: #ccc;
+$input-border: #ccc;
// TODO: Rename `$input-border-radius` to `$input-border-radius-base` in v4
//** Default `.form-control` border radius
// This has no effect on `<select>`s in some browsers, due to the limited stylability of `<select>`s in CSS.
-$input-border-radius: $border-radius-base;
+$input-border-radius: $border-radius-base;
//** Large `.form-control` border radius
-$input-border-radius-large: $border-radius-large;
+$input-border-radius-large: $border-radius-large;
//** Small `.form-control` border radius
-$input-border-radius-small: $border-radius-small;
+$input-border-radius-small: $border-radius-small;
//** Border color for inputs on focus
-$input-border-focus: $black;
+$input-border-focus: $black;
//** Placeholder text color
-$input-color-placeholder: $black;
+$input-color-placeholder: $black;
//** Default `.form-control` height
-$input-height-base: $line-height-computed;
+$input-height-base: $line-height-computed;
//** Large `.form-control` height
-$input-height-large: $input-height-base;
+$input-height-large: $input-height-base;
//** Small `.form-control` height
-$input-height-small: $input-height-base;
+$input-height-small: $input-height-base;
-$legend-color: $gray-dark;
-$legend-border-color: #e5e5e5;
+$legend-color: $gray-dark;
+$legend-border-color: #e5e5e5;
//** Background color for textual input addons
-$input-group-addon-bg: $gray-lighter;
+$input-group-addon-bg: $gray-lighter;
//** Border color for textual input addons
$input-group-addon-border-color: $input-border;
//** Disabled cursor for form controls and buttons.
-$cursor-disabled: not-allowed;
-
+$cursor-disabled: not-allowed;
//== Dropdowns
//
//## Dropdown menu container and contents.
//** Background for the dropdown menu.
-$dropdown-bg: $gray;
+$dropdown-bg: $gray;
//** Dropdown menu `border-color`.
-$dropdown-border: rgb(0,0,0);
+$dropdown-border: rgb(0, 0, 0);
//** Dropdown menu `border-color` **for IE8**.
-$dropdown-fallback-border: #ccc;
+$dropdown-fallback-border: #ccc;
//** Divider color for between dropdown items.
-$dropdown-divider-bg: $black;
+$dropdown-divider-bg: $black;
//** Dropdown link text color.
-$dropdown-link-color: $black;
+$dropdown-link-color: $black;
//** Hover color for dropdown links.
-$dropdown-link-hover-color: $gray;
+$dropdown-link-hover-color: $gray;
//** Hover background for dropdown links.
-$dropdown-link-hover-bg: $black;
+$dropdown-link-hover-bg: $black;
//** Active dropdown menu item text color.
-$dropdown-link-active-color: $component-active-color;
+$dropdown-link-active-color: $component-active-color;
//** Active dropdown menu item background color.
-$dropdown-link-active-bg: $component-active-bg;
+$dropdown-link-active-bg: $component-active-bg;
//** Disabled dropdown menu item background color.
-$dropdown-link-disabled-color: $gray-light;
+$dropdown-link-disabled-color: $gray-light;
//** Text color for headers within dropdown menus.
-$dropdown-header-color: $black;
+$dropdown-header-color: $black;
//** Deprecated `$dropdown-caret-color` as of v3.1.0
-$dropdown-caret-color: #000;
-
+$dropdown-caret-color: #000;
//-- Z-index master list
//
//
// Note: These variables are not generated into the Customizer.
-$zindex-navbar: 1000;
-$zindex-dropdown: 1000;
-$zindex-popover: 1060;
-$zindex-tooltip: 1070;
-$zindex-navbar-fixed: 1030;
-$zindex-modal: 1040;
-
+$zindex-navbar: 1000;
+$zindex-dropdown: 1000;
+$zindex-popover: 1060;
+$zindex-tooltip: 1070;
+$zindex-navbar-fixed: 1030;
+$zindex-modal: 1040;
//== Media queries breakpoints
//
// Extra small screen / phone
//** Deprecated `$screen-xs` as of v3.0.1
-$screen-xs: 480px;
+$screen-xs: 480px;
//** Deprecated `$screen-xs-min` as of v3.2.0
-$screen-xs-min: $screen-xs;
+$screen-xs-min: $screen-xs;
//** Deprecated `$screen-phone` as of v3.0.1
-$screen-phone: $screen-xs-min;
+$screen-phone: $screen-xs-min;
// Small screen / tablet
//** Deprecated `$screen-sm` as of v3.0.1
-$screen-sm: 768px;
-$screen-sm-min: $screen-sm;
+$screen-sm: 768px;
+$screen-sm-min: $screen-sm;
//** Deprecated `$screen-tablet` as of v3.0.1
-$screen-tablet: $screen-sm-min;
+$screen-tablet: $screen-sm-min;
// Medium screen / desktop
//** Deprecated `$screen-md` as of v3.0.1
-$screen-md: 992px;
-$screen-md-min: $screen-md;
+$screen-md: 992px;
+$screen-md-min: $screen-md;
//** Deprecated `$screen-desktop` as of v3.0.1
-$screen-desktop: $screen-md-min;
+$screen-desktop: $screen-md-min;
// Large screen / wide desktop
//** Deprecated `$screen-lg` as of v3.0.1
-$screen-lg: 1200px;
-$screen-lg-min: $screen-lg;
+$screen-lg: 1200px;
+$screen-lg-min: $screen-lg;
//** Deprecated `$screen-lg-desktop` as of v3.0.1
-$screen-lg-desktop: $screen-lg-min;
+$screen-lg-desktop: $screen-lg-min;
// So media queries don't overlap when required, provide a maximum
-$screen-xs-max: ($screen-sm-min - 1);
-$screen-sm-max: ($screen-md-min - 1);
-$screen-md-max: ($screen-lg-min - 1);
-
+$screen-xs-max: ($screen-sm-min - 1);
+$screen-sm-max: ($screen-md-min - 1);
+$screen-md-max: ($screen-lg-min - 1);
//== Grid system
//
//## Define your custom responsive grid.
//** Number of columns in the grid.
-$grid-columns: 12;
+$grid-columns: 12;
//** Padding between columns. Gets divided in half for the left and right.
-$grid-gutter-width: ($baseWidth * 2);
+$grid-gutter-width: ($baseWidth * 2);
// Navbar collapse
//** Point at which the navbar becomes uncollapsed.
-$grid-float-breakpoint: $screen-sm-min;
+$grid-float-breakpoint: $screen-sm-min;
//** Point at which the navbar begins collapsing.
$grid-float-breakpoint-max: ($grid-float-breakpoint);
-
//== Container sizes
//
//## Define the maximum width of `.container` for different screen sizes.
// Small screen / tablet
-$container-tablet: (720px + $grid-gutter-width);
+$container-tablet: (720px + $grid-gutter-width);
//** For `$screen-sm-min` and up.
-$container-sm: $container-tablet;
+$container-sm: $container-tablet;
// Medium screen / desktop
-$container-desktop: (940px + $grid-gutter-width);
+$container-desktop: (940px + $grid-gutter-width);
//** For `$screen-md-min` and up.
-$container-md: $container-desktop;
+$container-md: $container-desktop;
// Large screen / wide desktop
-$container-large-desktop: (1140px + $grid-gutter-width);
+$container-large-desktop: (1140px + $grid-gutter-width);
//** For `$screen-lg-min` and up.
-$container-lg: $container-large-desktop;
-
+$container-lg: $container-large-desktop;
//== Navbar
//
//##
// Basics of a navbar
-$navbar-height: 0px;
-$navbar-margin-bottom: $line-height-computed;
-$navbar-border-radius: $border-radius-base;
-$navbar-padding-horizontal: ($baseWidth * 2);
-$navbar-padding-vertical: 0;
-$navbar-collapse-max-height: 340px;
+$navbar-height: 0px;
+$navbar-margin-bottom: $line-height-computed;
+$navbar-border-radius: $border-radius-base;
+$navbar-padding-horizontal: ($baseWidth * 2);
+$navbar-padding-vertical: 0;
+$navbar-collapse-max-height: 340px;
-$navbar-default-color: $black;
-$navbar-default-bg: $grayLight;
-$navbar-default-border: $navbar-default-bg;
+$navbar-default-color: $black;
+$navbar-default-bg: $grayLight;
+$navbar-default-border: $navbar-default-bg;
// Navbar links
-$navbar-default-link-color: $black;
-$navbar-default-link-hover-color: $white;
-$navbar-default-link-hover-bg: $black;
-$navbar-default-link-active-color: $white;
-$navbar-default-link-active-bg: $black;
-$navbar-default-link-disabled-color: $gray;
-$navbar-default-link-disabled-bg: transparent;
+$navbar-default-link-color: $black;
+$navbar-default-link-hover-color: $white;
+$navbar-default-link-hover-bg: $black;
+$navbar-default-link-active-color: $white;
+$navbar-default-link-active-bg: $black;
+$navbar-default-link-disabled-color: $gray;
+$navbar-default-link-disabled-bg: transparent;
// Navbar brand label
-$navbar-default-brand-color: $navbar-default-link-color;
-$navbar-default-brand-hover-color: $navbar-default-brand-color;
-$navbar-default-brand-hover-bg: transparent;
+$navbar-default-brand-color: $navbar-default-link-color;
+$navbar-default-brand-hover-color: $navbar-default-brand-color;
+$navbar-default-brand-hover-bg: transparent;
// Navbar toggle
-$navbar-default-toggle-hover-bg: #ddd;
-$navbar-default-toggle-icon-bar-bg: #888;
-$navbar-default-toggle-border-color: #ddd;
-
+$navbar-default-toggle-hover-bg: #ddd;
+$navbar-default-toggle-icon-bar-bg: #888;
+$navbar-default-toggle-border-color: #ddd;
// Inverted navbar
// Reset inverted navbar basics
-$navbar-inverse-color: $gray;
-$navbar-inverse-bg: $black;
-$navbar-inverse-border: $navbar-inverse-bg;
+$navbar-inverse-color: $gray;
+$navbar-inverse-bg: $black;
+$navbar-inverse-border: $navbar-inverse-bg;
// Inverted navbar links
-$navbar-inverse-link-color: $gray-light;
-$navbar-inverse-link-hover-color: $black;
-$navbar-inverse-link-hover-bg: $grayLight;
-$navbar-inverse-link-active-color: $white;
-$navbar-inverse-link-active-bg: $grayDark;
-$navbar-inverse-link-disabled-color: $gray;
-$navbar-inverse-link-disabled-bg: transparent;
+$navbar-inverse-link-color: $gray-light;
+$navbar-inverse-link-hover-color: $black;
+$navbar-inverse-link-hover-bg: $grayLight;
+$navbar-inverse-link-active-color: $white;
+$navbar-inverse-link-active-bg: $grayDark;
+$navbar-inverse-link-disabled-color: $gray;
+$navbar-inverse-link-disabled-bg: transparent;
// Inverted navbar brand label
-$navbar-inverse-brand-color: $navbar-inverse-link-color;
-$navbar-inverse-brand-hover-color: #fff;
-$navbar-inverse-brand-hover-bg: transparent;
+$navbar-inverse-brand-color: $navbar-inverse-link-color;
+$navbar-inverse-brand-hover-color: #fff;
+$navbar-inverse-brand-hover-bg: transparent;
// Inverted navbar toggle
-$navbar-inverse-toggle-hover-bg: $grayLight;
-$navbar-inverse-toggle-icon-bar-bg: #fff;
-$navbar-inverse-toggle-border-color: #333;
-
+$navbar-inverse-toggle-hover-bg: $grayLight;
+$navbar-inverse-toggle-icon-bar-bg: #fff;
+$navbar-inverse-toggle-border-color: #333;
//== Navs
//
//##
//=== Shared nav styles
-$nav-link-padding: 0 $baseWidth;
-$nav-link-hover-bg: $gray-lighter;
+$nav-link-padding: 0 $baseWidth;
+$nav-link-hover-bg: $gray-lighter;
-$nav-disabled-link-color: $gray-light;
-$nav-disabled-link-hover-color: $gray-light;
+$nav-disabled-link-color: $gray-light;
+$nav-disabled-link-hover-color: $gray-light;
//== Tabs
-$nav-tabs-border-color: #ddd;
+$nav-tabs-border-color: #ddd;
-$nav-tabs-link-hover-border-color: $gray-lighter;
+$nav-tabs-link-hover-border-color: $gray-lighter;
-$nav-tabs-active-link-hover-bg: $black;
-$nav-tabs-active-link-hover-color: $white;
+$nav-tabs-active-link-hover-bg: $black;
+$nav-tabs-active-link-hover-color: $white;
-$nav-tabs-justified-active-link-border-color: $body-bg;
+$nav-tabs-justified-active-link-border-color: $body-bg;
//== Pills
-$nav-pills-border-radius: $border-radius-base;
-$nav-pills-active-link-hover-bg: $component-active-bg;
-$nav-pills-active-link-hover-color: $component-active-color;
-
+$nav-pills-border-radius: $border-radius-base;
+$nav-pills-active-link-hover-bg: $component-active-bg;
+$nav-pills-active-link-hover-color: $component-active-color;
//== Pagination
//
//##
-$pagination-color: $black;
-$pagination-bg: $gray;
-$pagination-border: #ddd;
-
-$pagination-hover-color: $link-hover-color;
-$pagination-hover-bg: $gray-lighter;
-$pagination-hover-border: #ddd;
+$pagination-color: $black;
+$pagination-bg: $gray;
+$pagination-border: #ddd;
-$pagination-active-color: #fff;
-$pagination-active-bg: $brand-primary;
-$pagination-active-border: $brand-primary;
+$pagination-hover-color: $link-hover-color;
+$pagination-hover-bg: $gray-lighter;
+$pagination-hover-border: #ddd;
-$pagination-disabled-color: $gray-light;
-$pagination-disabled-bg: #fff;
-$pagination-disabled-border: #ddd;
+$pagination-active-color: #fff;
+$pagination-active-bg: $brand-primary;
+$pagination-active-border: $brand-primary;
+$pagination-disabled-color: $gray-light;
+$pagination-disabled-bg: #fff;
+$pagination-disabled-border: #ddd;
//== Pager
//
//##
-$pager-bg: $pagination-bg;
-$pager-border: $pagination-border;
-$pager-border-radius: 0;
+$pager-bg: $pagination-bg;
+$pager-border: $pagination-border;
+$pager-border-radius: 0;
-$pager-hover-bg: $pagination-hover-bg;
+$pager-hover-bg: $pagination-hover-bg;
-$pager-active-bg: $pagination-active-bg;
-$pager-active-color: $pagination-active-color;
-
-$pager-disabled-color: $pagination-disabled-color;
+$pager-active-bg: $pagination-active-bg;
+$pager-active-color: $pagination-active-color;
+$pager-disabled-color: $pagination-disabled-color;
//== Jumbotron
//
//##
-$jumbotron-padding: ($ts) ($rhs + $baseWidth) ($bs) ($lhs + $baseWidth);
-$jumbotron-color: $white;
-$jumbotron-bg: transparent;
-$jumbotron-heading-color: inherit;
-$jumbotron-font-size: $font-size-base;
-
+$jumbotron-padding: ($ts) ($rhs + $baseWidth) ($bs) ($lhs + $baseWidth);
+$jumbotron-color: $white;
+$jumbotron-bg: transparent;
+$jumbotron-heading-color: inherit;
+$jumbotron-font-size: $font-size-base;
//== Form states and alerts
//
//## Define colors for form feedback states and, by default, alerts.
-$state-success-text: $green;
-$state-success-bg: $greenDark;
-$state-success-border: $state-success-bg;
-
-$state-info-text: $yellow;
-$state-info-bg: $brown;
-$state-info-border: $state-info-bg;
+$state-success-text: $green;
+$state-success-bg: $greenDark;
+$state-success-border: $state-success-bg;
-$state-warning-text: $magenta;
-$state-warning-bg: $magentaDark;
-$state-warning-border: $state-warning-bg;
+$state-info-text: $yellow;
+$state-info-bg: $brown;
+$state-info-border: $state-info-bg;
-$state-danger-text: $red;
-$state-danger-bg: $black;
-$state-danger-border: $state-danger-bg;
+$state-warning-text: $magenta;
+$state-warning-bg: $magentaDark;
+$state-warning-border: $state-warning-bg;
+$state-danger-text: $red;
+$state-danger-bg: $black;
+$state-danger-border: $state-danger-bg;
//== Tooltips
//
//##
//** Tooltip max width
-$tooltip-max-width: ($baseWidth * 25);
+$tooltip-max-width: ($baseWidth * 25);
//** Tooltip text color
-$tooltip-color: $white;
+$tooltip-color: $white;
//** Tooltip background color
-$tooltip-bg: $grayDark;
-$tooltip-opacity: 1;
+$tooltip-bg: $grayDark;
+$tooltip-opacity: 1;
//** Tooltip arrow width
-$tooltip-arrow-width: 0px;
+$tooltip-arrow-width: 0px;
//** Tooltip arrow color
-$tooltip-arrow-color: $tooltip-bg;
-
+$tooltip-arrow-color: $tooltip-bg;
//== Popovers
//
//##
//** Popover body background color
-$popover-bg: $gray;
+$popover-bg: $gray;
//** Popover maximum width
-$popover-max-width: ($baseWidth * 20);
+$popover-max-width: ($baseWidth * 20);
//** Popover border color
-$popover-border-color: rgb(0,0,0);
+$popover-border-color: rgb(0, 0, 0);
//** Popover fallback border color
-$popover-fallback-border-color: #ccc;
+$popover-fallback-border-color: #ccc;
//** Popover title background color
-$popover-title-bg: $greenDark;
+$popover-title-bg: $greenDark;
//** Popover arrow width
-$popover-arrow-width: 10px;
+$popover-arrow-width: 10px;
//** Popover arrow color
-$popover-arrow-color: $popover-bg;
+$popover-arrow-color: $popover-bg;
//** Popover outer arrow width
-$popover-arrow-outer-width: ($popover-arrow-width + 1);
+$popover-arrow-outer-width: ($popover-arrow-width + 1);
//** Popover outer arrow color
-$popover-arrow-outer-color: $popover-border-color;
+$popover-arrow-outer-color: $popover-border-color;
//** Popover outer arrow fallback color
-$popover-arrow-outer-fallback-color: $popover-fallback-border-color;
-
+$popover-arrow-outer-fallback-color: $popover-fallback-border-color;
//== Labels
//
//##
//** Default label background color
-$label-default-bg: $gray-light;
+$label-default-bg: $gray-light;
//** Primary label background color
-$label-primary-bg: $brand-primary-bg;
+$label-primary-bg: $brand-primary-bg;
//** Success label background color
-$label-success-bg: $brand-success;
+$label-success-bg: $brand-success;
//** Info label background color
-$label-info-bg: $brand-info;
+$label-info-bg: $brand-info;
//** Warning label background color
-$label-warning-bg: $brand-warning;
+$label-warning-bg: $brand-warning;
//** Danger label background color
-$label-danger-bg: $brand-danger;
+$label-danger-bg: $brand-danger;
//** Default label text color
-$label-color: #fff;
+$label-color: #fff;
//** Default text color of a linked label
-$label-link-hover-color: #fff;
-
+$label-link-hover-color: #fff;
//== Modals
//
//##
//** Padding applied to the modal body
-$modal-inner-padding: 0 $baseWidth;
+$modal-inner-padding: 0 $baseWidth;
//** Padding applied to the modal title
-$modal-title-padding: 0 $baseWidth;
+$modal-title-padding: 0 $baseWidth;
//** Modal title line-height
-$modal-title-line-height: $line-height-base;
+$modal-title-line-height: $line-height-base;
//** Background color of modal content area
-$modal-content-bg: $gray;
+$modal-content-bg: $gray;
//** Modal content border color
-$modal-content-border-color: rgb(0,0,0);
+$modal-content-border-color: rgb(0, 0, 0);
//** Modal content border color **for IE8**
-$modal-content-fallback-border-color: #999;
+$modal-content-fallback-border-color: #999;
//** Modal backdrop background color
-$modal-backdrop-bg: #000;
+$modal-backdrop-bg: #000;
//** Modal backdrop opacity
// $modal-backdrop-opacity: @include 5;
//** Modal header border color
-$modal-header-border-color: #e5e5e5;
+$modal-header-border-color: #e5e5e5;
//** Modal footer border color
-$modal-footer-border-color: $modal-header-border-color;
-
-$modal-lg: 900px;
-$modal-md: 600px;
-$modal-sm: 300px;
+$modal-footer-border-color: $modal-header-border-color;
+$modal-lg: 900px;
+$modal-md: 600px;
+$modal-sm: 300px;
//== Alerts
//
//## Define alert colors, border radius, and padding.
-$alert-padding: $line-height-base ($baseWidth * 2);
-$alert-border-radius: $border-radius-base;
-$alert-link-font-weight: normal;
+$alert-padding: $line-height-base ($baseWidth * 2);
+$alert-border-radius: $border-radius-base;
+$alert-link-font-weight: normal;
-$alert-success-bg: $state-success-bg;
-$alert-success-text: $state-success-text;
-$alert-success-border: $state-success-border;
+$alert-success-bg: $state-success-bg;
+$alert-success-text: $state-success-text;
+$alert-success-border: $state-success-border;
-$alert-info-bg: $state-info-bg;
-$alert-info-text: $state-info-text;
-$alert-info-border: $state-info-border;
+$alert-info-bg: $state-info-bg;
+$alert-info-text: $state-info-text;
+$alert-info-border: $state-info-border;
-$alert-warning-bg: $state-warning-bg;
-$alert-warning-text: $state-warning-text;
-$alert-warning-border: $state-warning-border;
-
-$alert-danger-bg: $state-danger-bg;
-$alert-danger-text: $state-danger-text;
-$alert-danger-border: $state-danger-border;
+$alert-warning-bg: $state-warning-bg;
+$alert-warning-text: $state-warning-text;
+$alert-warning-border: $state-warning-border;
+$alert-danger-bg: $state-danger-bg;
+$alert-danger-text: $state-danger-text;
+$alert-danger-border: $state-danger-border;
//== Progress bars
//
//##
//** Background color of the whole progress component
-$progress-bg: $black;
+$progress-bg: $black;
//** Progress bar text color
-$progress-bar-color: $black;
+$progress-bar-color: $black;
//** Variable for setting rounded corners on progress bar.
-$progress-border-radius: $border-radius-base;
+$progress-border-radius: $border-radius-base;
//** Default progress bar color
-$progress-bar-bg: $brand-primary;
+$progress-bar-bg: $brand-primary;
//** Success progress bar color
-$progress-bar-success-bg: $brand-success;
+$progress-bar-success-bg: $brand-success;
//** Warning progress bar color
-$progress-bar-warning-bg: $brand-warning;
+$progress-bar-warning-bg: $brand-warning;
//** Danger progress bar color
-$progress-bar-danger-bg: $brand-danger;
+$progress-bar-danger-bg: $brand-danger;
//** Info progress bar color
-$progress-bar-info-bg: $brand-info;
-
+$progress-bar-info-bg: $brand-info;
//== List group
//
//##
//** Background color on `.list-group-item`
-$list-group-bg: $gray;
+$list-group-bg: $gray;
//** `.list-group-item` border color
-$list-group-border: #ddd;
+$list-group-border: #ddd;
//** List group border radius
-$list-group-border-radius: $border-radius-base;
+$list-group-border-radius: $border-radius-base;
//** Background color of single list items on hover
-$list-group-hover-bg: $black;
+$list-group-hover-bg: $black;
//** Text color of active list items
-$list-group-active-color: $component-active-color;
+$list-group-active-color: $component-active-color;
//** Background color of active list items
-$list-group-active-bg: $component-active-bg;
+$list-group-active-bg: $component-active-bg;
//** Border color of active list elements
-$list-group-active-border: $list-group-active-bg;
+$list-group-active-border: $list-group-active-bg;
//** Text color for content within active list items
-$list-group-active-text-color: $component-active-color;
+$list-group-active-text-color: $component-active-color;
//** Text color of disabled list items
-$list-group-disabled-color: $gray-dark;
+$list-group-disabled-color: $gray-dark;
//** Background color of disabled list items
-$list-group-disabled-bg: $gray-lighter;
+$list-group-disabled-bg: $gray-lighter;
//** Text color for content within disabled list items
$list-group-disabled-text-color: $list-group-disabled-color;
-$list-group-link-color: $black;
-$list-group-link-hover-color: $list-group-link-color;
+$list-group-link-color: $black;
+$list-group-link-hover-color: $list-group-link-color;
$list-group-link-heading-color: #333;
-
//== Panels
//
//##
-$panel-bg: $gray;
-$panel-body-padding: 0 $rhsNB 0 $lhsNB;
-$panel-heading-padding: 0 $rhsNB 0 $lhsNB;
-$panel-footer-padding: $panel-heading-padding;
-$panel-border-radius: $border-radius-base;
+$panel-bg: $gray;
+$panel-body-padding: 0 $rhsNB 0 $lhsNB;
+$panel-heading-padding: 0 $rhsNB 0 $lhsNB;
+$panel-footer-padding: $panel-heading-padding;
+$panel-border-radius: $border-radius-base;
//** Border color for elements within panels
-$panel-inner-border: #ddd;
-$panel-footer-bg: #f5f5f5;
-
-$panel-default-text: $white;
-$panel-default-border: #ddd;
-$panel-default-heading-bg: $grayDark;
+$panel-inner-border: #ddd;
+$panel-footer-bg: #f5f5f5;
-$panel-primary-text: $white;
-$panel-primary-border: $brand-primary;
-$panel-primary-heading-bg: $cyanDark;
+$panel-default-text: $white;
+$panel-default-border: #ddd;
+$panel-default-heading-bg: $grayDark;
-$panel-success-text: $state-success-text;
-$panel-success-border: $state-success-border;
-$panel-success-heading-bg: $state-success-bg;
+$panel-primary-text: $white;
+$panel-primary-border: $brand-primary;
+$panel-primary-heading-bg: $cyanDark;
-$panel-info-text: $state-info-text;
-$panel-info-border: $state-info-border;
-$panel-info-heading-bg: $state-info-bg;
+$panel-success-text: $state-success-text;
+$panel-success-border: $state-success-border;
+$panel-success-heading-bg: $state-success-bg;
-$panel-warning-text: $state-warning-text;
-$panel-warning-border: $state-warning-border;
-$panel-warning-heading-bg: $state-warning-bg;
+$panel-info-text: $state-info-text;
+$panel-info-border: $state-info-border;
+$panel-info-heading-bg: $state-info-bg;
-$panel-danger-text: $state-danger-text;
-$panel-danger-border: $state-danger-border;
-$panel-danger-heading-bg: $state-danger-bg;
+$panel-warning-text: $state-warning-text;
+$panel-warning-border: $state-warning-border;
+$panel-warning-heading-bg: $state-warning-bg;
+$panel-danger-text: $state-danger-text;
+$panel-danger-border: $state-danger-border;
+$panel-danger-heading-bg: $state-danger-bg;
//== Thumbnails
//
//##
//** Padding around the thumbnail image
-$thumbnail-padding: 4px;
+$thumbnail-padding: 4px;
//** Thumbnail background color
-$thumbnail-bg: $body-bg;
+$thumbnail-bg: $body-bg;
//** Thumbnail border color
-$thumbnail-border: #ddd;
+$thumbnail-border: #ddd;
//** Thumbnail border radius
-$thumbnail-border-radius: $border-radius-base;
+$thumbnail-border-radius: $border-radius-base;
//** Custom text color for thumbnail captions
-$thumbnail-caption-color: $text-color;
+$thumbnail-caption-color: $text-color;
//** Padding around the thumbnail caption
-$thumbnail-caption-padding: 9px;
-
+$thumbnail-caption-padding: 9px;
//== Wells
//
//##
-$well-bg: $greenDark;
-$well-border: $well-bg;
-
+$well-bg: $greenDark;
+$well-border: $well-bg;
//== Badges
//
//##
-$badge-color: $black;
+$badge-color: $black;
//** Linked badge text color on hover
-$badge-link-hover-color: #fff;
-$badge-bg: $gray-light;
+$badge-link-hover-color: #fff;
+$badge-bg: $gray-light;
//** Badge text color in active nav link
-$badge-active-color: $link-color;
+$badge-active-color: $link-color;
//** Badge background color in active nav link
-$badge-active-bg: $black;
-
-$badge-font-weight: normal;
-$badge-line-height: $line-height-base;
-$badge-border-radius: 0;
+$badge-active-bg: $black;
+$badge-font-weight: normal;
+$badge-line-height: $line-height-base;
+$badge-border-radius: 0;
//== Breadcrumbs
//
//##
-$breadcrumb-padding-vertical: 8px;
+$breadcrumb-padding-vertical: 8px;
$breadcrumb-padding-horizontal: 15px;
//** Breadcrumb background color
-$breadcrumb-bg: #f5f5f5;
+$breadcrumb-bg: #f5f5f5;
//** Breadcrumb text color
-$breadcrumb-color: #ccc;
+$breadcrumb-color: #ccc;
//** Text color of current page in the breadcrumb
-$breadcrumb-active-color: $gray-light;
+$breadcrumb-active-color: $gray-light;
//** Textual separator for between breadcrumb elements
-$breadcrumb-separator: "/";
-
+$breadcrumb-separator: "/";
//== Carousel
//
//##
-$carousel-text-shadow: none;
-
-$carousel-control-color: #fff;
-$carousel-control-width: 15%;
-$carousel-control-opacity: 1;
-$carousel-control-font-size: $font-size-base;
+$carousel-text-shadow: none;
-$carousel-indicator-active-bg: #fff;
-$carousel-indicator-border-color: #fff;
+$carousel-control-color: #fff;
+$carousel-control-width: 15%;
+$carousel-control-opacity: 1;
+$carousel-control-font-size: $font-size-base;
-$carousel-caption-color: #fff;
+$carousel-indicator-active-bg: #fff;
+$carousel-indicator-border-color: #fff;
+$carousel-caption-color: #fff;
//== Close
//
//##
-$close-font-weight: normal;
-$close-color: #000;
-$close-text-shadow: none;
-
+$close-font-weight: normal;
+$close-color: #000;
+$close-text-shadow: none;
//== Code
//
//##
-$code-color: #c7254e;
-$code-bg: #f9f2f4;
-
-$kbd-color: #fff;
-$kbd-bg: #333;
+$code-color: #c7254e;
+$code-bg: #f9f2f4;
-$pre-bg: #f5f5f5;
-$pre-color: $gray-dark;
-$pre-border-color: #ccc;
-$pre-scrollable-max-height: 340px;
+$kbd-color: #fff;
+$kbd-bg: #333;
+$pre-bg: #f5f5f5;
+$pre-color: $gray-dark;
+$pre-border-color: #ccc;
+$pre-scrollable-max-height: 340px;
//== Type
//
//** Horizontal offset for forms and lists.
$component-offset-horizontal: 180px;
//** Text muted color
-$text-muted: $gray-dark;
+$text-muted: $gray-dark;
//** Abbreviations and acronyms border color
-$abbr-border-color: $gray-light;
+$abbr-border-color: $gray-light;
//** Headings small color
-$headings-small-color: $gray-light;
+$headings-small-color: $gray-light;
//** Blockquote small color
-$blockquote-small-color: $gray-light;
+$blockquote-small-color: $gray-light;
//** Blockquote font size
-$blockquote-font-size: $font-size-base;
+$blockquote-font-size: $font-size-base;
//** Blockquote border color
-$blockquote-border-color: $gray-lighter;
+$blockquote-border-color: $gray-lighter;
//** Page header border color
-$page-header-border-color: $gray-lighter;
+$page-header-border-color: $gray-lighter;
//** Width of horizontal description list titles
-$dl-horizontal-offset: $component-offset-horizontal;
+$dl-horizontal-offset: $component-offset-horizontal;
//** Horizontal line color.
-$hr-border: $black;
+$hr-border: $black;
-
$white: #fff;
$gray-100: #f8f9fa;
$gray-200: #ebebeb;
$body-bg: $gray-900;
$body-color: $gray-300;
$link-color: $success;
-$font-family-sans-serif: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+$font-family-sans-serif: "Lato", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji",
+ "Segoe UI Emoji", "Segoe UI Symbol";
$font-size-base: 0.9375rem;
$h1-font-size: 3rem;
$h2-font-size: 2.5rem;
$nav-link-padding-x: 2rem;
$nav-link-disabled-color: $gray-500;
$nav-tabs-border-color: $gray-700;
-$nav-tabs-link-hover-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent;
+$nav-tabs-link-hover-border-color: $nav-tabs-border-color $nav-tabs-border-color
+ transparent;
$nav-tabs-link-active-color: $white;
-$nav-tabs-link-active-border-color: $nav-tabs-border-color $nav-tabs-border-color transparent;
+$nav-tabs-link-active-border-color: $nav-tabs-border-color
+ $nav-tabs-border-color transparent;
$navbar-padding-y: 1rem;
-$navbar-dark-color: rgba($white,.6);
+$navbar-dark-color: rgba($white, 0.6);
$navbar-dark-hover-color: $white;
-$navbar-light-color: rgba($white,.6);
+$navbar-light-color: rgba($white, 0.6);
$navbar-light-hover-color: $white;
$navbar-light-active-color: $white;
-$navbar-light-toggler-border-color: rgba($gray-900, .1);
+$navbar-light-toggler-border-color: rgba($gray-900, 0.1);
$pagination-color: $white;
$pagination-bg: $success;
$pagination-border-width: 0;
$custom-select-color: $white;
$input-bg: $secondary;
$input-color: $white;
-$input-disabled-bg: darken($secondary, 10%);;
+$input-disabled-bg: darken($secondary, 10%);
$light: $gray-800;
$navbar-light-brand-color: $navbar-dark-active-color;
-$navbar-light-brand-hover-color: $navbar-dark-active-color;
\ No newline at end of file
+$navbar-light-brand-hover-color: $navbar-dark-active-color;
-
-$blue: #5555Ff;
-$cyan: #55FFFF;
-$green: #55FF55;
-$indigo: #FF55FF;
-$red: #FF5555;
-$yellow: #FEFE54;
-$orange: #A85400;
-$pink: #FE54FE;
-$purple: #FE5454;
-$primary: #FEFE54;
+$blue: #5555ff;
+$cyan: #55ffff;
+$green: #55ff55;
+$indigo: #ff55ff;
+$red: #ff5555;
+$yellow: #fefe54;
+$orange: #a85400;
+$pink: #fe54fe;
+$purple: #fe5454;
+$primary: #fefe54;
$body-bg: #000084;
$gray-300: #bbb;
$body-color: $gray-300;
$font-family-monospace: DOS, Monaco, Menlo, Consolas, "Courier New", monospace;
$navbar-dark-color: $gray-300;
$navbar-light-brand-color: $gray-300;
-$success: #00AA00;
-$danger: #AA0000;
-$info: #00AAAA;
-$warning: #AA00AA;
+$success: #00aa00;
+$danger: #aa0000;
+$info: #00aaaa;
+$warning: #aa00aa;
$navbar-dark-active-color: $gray-100;
$enable-rounded: false;
$input-color: $white;
$input-bg: rgb(102, 102, 102);
$input-disabled-bg: $gray-800;
$nav-tabs-link-active-color: $gray-100;
-$navbar-dark-hover-color: rgba($gray-300, .75);
+$navbar-dark-hover-color: rgba($gray-300, 0.75);
$light: $gray-800;
$navbar-light-disabled-color: $gray-800;
$navbar-light-active-color: $gray-100;
$card-border-color: $white;
$input-placeholder-color: $gray-500;
$mark-bg: #463b00;
-$secondary: $gray-900;
\ No newline at end of file
+$secondary: $gray-900;
-
$white: #ffffff;
$orange: #f1641e;
$cyan: #02bdc2;
-$green: #00C853;
+$green: #00c853;
$secondary: $green;
$body-color: $gray-700;
-$link-color: theme-color("primary");;
+$link-color: theme-color("primary");
$primary: $orange;
$red: #d8486a;
$border-radius: 0.5rem;
$border-radius-lg: 0.5rem;
$border-radius-sm: 1rem;
-$font-family-sans-serif: -apple-system,BlinkMacSystemFont,"Droid Sans","Segoe UI","Helvetica",Arial,sans-serif;
+$font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Droid Sans",
+ "Segoe UI", "Helvetica", Arial, sans-serif;
$headings-color: $gray-700;
-$input-btn-focus-color: rgba($component-active-bg, .75);
+$input-btn-focus-color: rgba($component-active-bg, 0.75);
$form-feedback-valid-color: theme-color("info");
$navbar-light-color: $gray-600;
$black: #222222;
-$navbar-dark-toggler-border-color: rgba($black, .1);
+$navbar-dark-toggler-border-color: rgba($black, 0.1);
$navbar-light-active-color: $gray-900;
$card-color: $gray-700;
$card-cap-color: $gray-700;
-
$blue: #01cdfe;
$indigo: #b967ff;
$purple: #b967ff;
$secondary: $blue;
$text-muted: $gray-500;
$primary: $pink;
-$navbar-light-hover-color: rgba($primary, .7);
-$light: darken($gray-100,1.5);
+$navbar-light-hover-color: rgba($primary, 0.7);
+$light: darken($gray-100, 1.5);
$font-family-sans-serif: "Lucida Console", Monaco, monospace;
$card-bg: $body-bg;
-$navbar-dark-color: rgba($body-bg, .5);
-$navbar-light-active-color: rgba($gray-200, .9);
-$navbar-light-disabled-color: rgba($gray-200, .3);
-$navbar-light-color: rgba($white, .5);
+$navbar-dark-color: rgba($body-bg, 0.5);
+$navbar-light-active-color: rgba($gray-200, 0.9);
+$navbar-light-disabled-color: rgba($gray-200, 0.3);
+$navbar-light-color: rgba($white, 0.5);
$input-bg: $gray-700;
$input-color: $gray-200;
$input-disabled-bg: $gray-800;
$secondary: $blue;
$text-muted: $gray-500;
$primary: $pink;
-$navbar-light-hover-color: rgba($primary, .7);
-$light: darken($gray-100,1.5);
+$navbar-light-hover-color: rgba($primary, 0.7);
+$light: darken($gray-100, 1.5);
$font-family-sans-serif: "Lucida Console", Monaco, monospace;
-import { hydrate } from 'inferno-hydrate';
-import { BrowserRouter } from 'inferno-router';
-import { initializeSite } from '../shared/initialize';
-import { App } from '../shared/components/app';
+import { hydrate } from "inferno-hydrate";
+import { BrowserRouter } from "inferno-router";
+import { initializeSite } from "../shared/initialize";
+import { App } from "../shared/components/app";
const site = window.isoData.site_res;
initializeSite(site);
</BrowserRouter>
);
-hydrate(wrapper, document.getElementById('root'));
+hydrate(wrapper, document.getElementById("root"));
-import serialize from 'serialize-javascript';
-import express from 'express';
-import { StaticRouter } from 'inferno-router';
-import { renderToString } from 'inferno-server';
-import { matchPath } from 'inferno-router';
-import path from 'path';
-import { App } from '../shared/components/app';
+import serialize from "serialize-javascript";
+import express from "express";
+import { StaticRouter } from "inferno-router";
+import { renderToString } from "inferno-server";
+import { matchPath } from "inferno-router";
+import path from "path";
+import { App } from "../shared/components/app";
import {
ILemmyConfig,
InitialFetchRequest,
IsoData,
-} from '../shared/interfaces';
-import { routes } from '../shared/routes';
-import IsomorphicCookie from 'isomorphic-cookie';
-import { GetSite, LemmyHttp } from 'lemmy-js-client';
-import process from 'process';
-import { Helmet } from 'inferno-helmet';
-import { initializeSite } from '../shared/initialize';
-import { httpUri } from '../shared/env';
-import { IncomingHttpHeaders } from 'http';
-import { setOptionalAuth } from '../shared/utils';
+} from "../shared/interfaces";
+import { routes } from "../shared/routes";
+import IsomorphicCookie from "isomorphic-cookie";
+import { GetSite, LemmyHttp } from "lemmy-js-client";
+import process from "process";
+import { Helmet } from "inferno-helmet";
+import { initializeSite } from "../shared/initialize";
+import { httpUri } from "../shared/env";
+import { IncomingHttpHeaders } from "http";
+import { setOptionalAuth } from "../shared/utils";
const server = express();
const port = 1234;
server.use(express.json());
server.use(express.urlencoded({ extended: false }));
-server.use('/static', express.static(path.resolve('./dist')));
+server.use("/static", express.static(path.resolve("./dist")));
// server.use(cookieParser());
-server.get('/*', async (req, res) => {
+server.get("/*", async (req, res) => {
const activeRoute = routes.find(route => matchPath(req.path, route)) || {};
const context = {} as any;
- let auth: string = IsomorphicCookie.load('jwt', req);
+ let auth: string = IsomorphicCookie.load("jwt", req);
let getSiteForm: GetSite = {};
setOptionalAuth(getSiteForm, auth);
return res.redirect(`/404?err=${errCode}`);
}
- let acceptLang = req.headers['accept-language']
- ? req.headers['accept-language'].split(',')[0]
- : 'en';
+ let acceptLang = req.headers["accept-language"]
+ ? req.headers["accept-language"].split(",")[0]
+ : "en";
let lang = site.my_user
- ? site.my_user.lang == 'browser'
+ ? site.my_user.lang == "browser"
? acceptLang
- : 'en'
+ : "en"
: acceptLang;
let isoData: IsoData = {
);
const root = renderToString(wrapper);
- const cspStr = process.env.LEMMY_EXTERNAL_HOST ? renderToString(cspHtml) : '';
+ const cspStr = process.env.LEMMY_EXTERNAL_HOST ? renderToString(cspHtml) : "";
const helmet = Helmet.renderStatic();
const config: ILemmyConfig = { wsHost: process.env.LEMMY_WS_HOST };
let out = {
host: headers.host,
};
- if (headers['x-real-ip']) {
- out['x-real-ip'] = headers['x-real-ip'];
+ if (headers["x-real-ip"]) {
+ out["x-real-ip"] = headers["x-real-ip"];
}
- if (headers['x-forwarded-for']) {
- out['x-forwarded-for'] = headers['x-forwarded-for'];
+ if (headers["x-forwarded-for"]) {
+ out["x-forwarded-for"] = headers["x-forwarded-for"];
}
return out;
}
-process.on('SIGINT', () => {
- console.info('Interrupted');
+process.on("SIGINT", () => {
+ console.info("Interrupted");
process.exit(0);
});
-import { register } from 'register-service-worker';
+import { register } from "register-service-worker";
-register('/service-worker.js', {
- registrationOptions: { scope: './' },
+register("/service-worker.js", {
+ registrationOptions: { scope: "./" },
ready() {
- console.log('Service worker is active.');
+ console.log("Service worker is active.");
},
registered() {
- console.log('Service worker has been registered.');
+ console.log("Service worker has been registered.");
},
cached() {
- console.log('Content has been cached for offline use.');
+ console.log("Content has been cached for offline use.");
},
updatefound() {
- console.log('New content is downloading.');
+ console.log("New content is downloading.");
},
updated() {
- console.log('New content is available; please refresh.');
+ console.log("New content is available; please refresh.");
},
offline() {
console.log(
- 'No internet connection found. App is running in offline mode.'
+ "No internet connection found. App is running in offline mode."
);
},
error(error) {
- console.error('Error during service worker registration:', error);
+ console.error("Error during service worker registration:", error);
},
});
-import { Component, linkEvent } from 'inferno';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Subscription } from "rxjs";
import {
UserOperation,
SiteResponse,
SaveSiteConfig,
GetSiteConfigResponse,
GetSiteConfig,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
wsJsonToRes,
capitalizeFirstLetter,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import autosize from 'autosize';
-import { SiteForm } from './site-form';
-import { UserListing } from './user-listing';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+} from "../utils";
+import autosize from "autosize";
+import { SiteForm } from "./site-form";
+import { UserListing } from "./user-listing";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
interface AdminSettingsState {
siteRes: GetSiteResponse;
}
get documentTitle(): string {
- return `${i18n.t('admin_settings')} - ${
+ return `${i18n.t("admin_settings")} - ${
this.state.siteRes.site_view.site.name
}`;
}
admins() {
return (
<>
- <h5>{capitalizeFirstLetter(i18n.t('admins'))}</h5>
+ <h5>{capitalizeFirstLetter(i18n.t("admins"))}</h5>
<ul class="list-unstyled">
{this.state.siteRes.admins.map(admin => (
<li class="list-inline-item">
bannedUsers() {
return (
<>
- <h5>{i18n.t('banned_users')}</h5>
+ <h5>{i18n.t("banned_users")}</h5>
<ul class="list-unstyled">
{this.state.siteRes.banned.map(banned => (
<li class="list-inline-item">
adminSettings() {
return (
<div>
- <h5>{i18n.t('admin_settings')}</h5>
+ <h5>{i18n.t("admin_settings")}</h5>
<form onSubmit={linkEvent(this, this.handleSiteConfigSubmit)}>
<div class="form-group row">
<label
class="col-12 col-form-label"
htmlFor={this.siteConfigTextAreaId}
>
- {i18n.t('site_config')}
+ {i18n.t("site_config")}
</label>
<div class="col-12">
<textarea
{this.state.siteConfigLoading ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
)}
</button>
</div>
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
- this.context.router.history.push('/');
+ toast(i18n.t(msg.error), "danger");
+ this.context.router.history.push("/");
this.state.loading = false;
this.setState(this.state);
return;
let data = wsJsonToRes<SiteResponse>(msg).data;
this.state.siteRes.site_view = data.site_view;
this.setState(this.state);
- toast(i18n.t('site_saved'));
+ toast(i18n.t("site_saved"));
} else if (op == UserOperation.GetSiteConfig) {
let data = wsJsonToRes<GetSiteConfigResponse>(msg).data;
this.state.siteConfigRes = data;
this.state.siteConfigRes = data;
this.state.siteConfigForm.config_hjson = this.state.siteConfigRes.config_hjson;
this.state.siteConfigLoading = false;
- toast(i18n.t('site_saved'));
+ toast(i18n.t("site_saved"));
this.setState(this.state);
}
}
-import { Component } from 'inferno';
-import { Route, Switch } from 'inferno-router';
-import { Provider } from 'inferno-i18next';
-import { Helmet } from 'inferno-helmet';
-import { i18n } from '../i18next';
-import { routes } from '../routes';
-import { Navbar } from './navbar';
-import { Footer } from './footer';
-import { NoMatch } from './no-match';
-import { Theme } from './theme';
-import { Symbols } from './symbols';
-import { GetSiteResponse } from 'lemmy-js-client';
-import './styles.scss';
+import { Component } from "inferno";
+import { Route, Switch } from "inferno-router";
+import { Provider } from "inferno-i18next";
+import { Helmet } from "inferno-helmet";
+import { i18n } from "../i18next";
+import { routes } from "../routes";
+import { Navbar } from "./navbar";
+import { Footer } from "./footer";
+import { NoMatch } from "./no-match";
+import { Theme } from "./theme";
+import { Symbols } from "./symbols";
+import { GetSiteResponse } from "lemmy-js-client";
+import "./styles.scss";
export interface AppProps {
siteRes: GetSiteResponse;
-import { Component } from 'inferno';
-import { PictrsImage } from './pictrs-image';
+import { Component } from "inferno";
+import { PictrsImage } from "./pictrs-image";
interface BannerIconHeaderProps {
banner?: string;
-import { Component } from 'inferno';
-import { i18n } from '../i18next';
-import { Icon } from './icon';
+import { Component } from "inferno";
+import { i18n } from "../i18next";
+import { Icon } from "./icon";
interface CakeDayProps {
creatorName: string;
}
cakeDayTippy(): string {
- return i18n.t('cake_day_info', { creator_name: this.props.creatorName });
+ return i18n.t("cake_day_info", { creator_name: this.props.creatorName });
}
}
-import { Component } from 'inferno';
-import { Link } from 'inferno-router';
-import { Subscription } from 'rxjs';
+import { Component } from "inferno";
+import { Link } from "inferno-router";
+import { Subscription } from "rxjs";
import {
CreateComment,
EditComment,
UserOperation,
CommentResponse,
-} from 'lemmy-js-client';
-import { CommentNode as CommentNodeI } from '../interfaces';
+} from "lemmy-js-client";
+import { CommentNode as CommentNodeI } from "../interfaces";
import {
authField,
capitalizeFirstLetter,
wsJsonToRes,
wsSubscribe,
wsUserOp,
-} from '../utils';
-import { WebSocketService, UserService } from '../services';
-import { i18n } from '../i18next';
-import { T } from 'inferno-i18next';
-import { MarkdownTextArea } from './markdown-textarea';
-import { Icon } from './icon';
+} from "../utils";
+import { WebSocketService, UserService } from "../services";
+import { i18n } from "../i18next";
+import { T } from "inferno-i18next";
+import { MarkdownTextArea } from "./markdown-textarea";
+import { Icon } from "./icon";
interface CommentFormProps {
postId?: number;
private subscription: Subscription;
private emptyState: CommentFormState = {
buttonTitle: !this.props.node
- ? capitalizeFirstLetter(i18n.t('post'))
+ ? capitalizeFirstLetter(i18n.t("post"))
: this.props.edit
- ? capitalizeFirstLetter(i18n.t('save'))
- : capitalizeFirstLetter(i18n.t('reply')),
+ ? capitalizeFirstLetter(i18n.t("save"))
+ : capitalizeFirstLetter(i18n.t("reply")),
finished: false,
- formId: 'empty_form',
+ formId: "empty_form",
};
constructor(props: any, context: any) {
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
import {
CreateCommentLike,
DeleteComment,
TransferSite,
CommentView,
UserMentionView,
-} from 'lemmy-js-client';
-import { CommentNode as CommentNodeI, BanType } from '../interfaces';
-import { WebSocketService, UserService } from '../services';
+} from "lemmy-js-client";
+import { CommentNode as CommentNodeI, BanType } from "../interfaces";
+import { WebSocketService, UserService } from "../services";
import {
mdToHtml,
getUnixTime,
colorList,
wsClient,
authField,
-} from '../utils';
-import moment from 'moment';
-import { MomentTime } from './moment-time';
-import { CommentForm } from './comment-form';
-import { CommentNodes } from './comment-nodes';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { Icon, Spinner } from './icon';
-import { i18n } from '../i18next';
+} from "../utils";
+import moment from "moment";
+import { MomentTime } from "./moment-time";
+import { CommentForm } from "./comment-form";
+import { CommentNodes } from "./comment-nodes";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { Icon, Spinner } from "./icon";
+import { i18n } from "../i18next";
interface CommentNodeState {
showReply: boolean;
return (
<div
className={`comment ${
- cv.comment.parent_id && !this.props.noIndent ? 'ml-1' : ''
+ cv.comment.parent_id && !this.props.noIndent ? "ml-1" : ""
}`}
>
<div
id={`comment-${cv.comment.id}`}
className={`details comment-node py-2 ${
- !this.props.noBorder ? 'border-top border-light' : ''
- } ${this.isCommentNew ? 'mark' : ''}`}
+ !this.props.noBorder ? "border-top border-light" : ""
+ } ${this.isCommentNew ? "mark" : ""}`}
style={
!this.props.noIndent &&
cv.comment.parent_id &&
}
>
<div
- class={`${!this.props.noIndent && cv.comment.parent_id && 'ml-2'}`}
+ class={`${!this.props.noIndent && cv.comment.parent_id && "ml-2"}`}
>
<div class="d-flex flex-wrap align-items-center text-muted small">
<span class="mr-2">
{this.isMod && (
<div className="badge badge-light d-none d-sm-inline mr-2">
- {i18n.t('mod')}
+ {i18n.t("mod")}
</div>
)}
{this.isAdmin && (
<div className="badge badge-light d-none d-sm-inline mr-2">
- {i18n.t('admin')}
+ {i18n.t("admin")}
</div>
)}
{this.isPostCreator && (
<div className="badge badge-light d-none d-sm-inline mr-2">
- {i18n.t('creator')}
+ {i18n.t("creator")}
</div>
)}
{(cv.creator_banned_from_community || cv.creator.banned) && (
<div className="badge badge-danger mr-2">
- {i18n.t('banned')}
+ {i18n.t("banned")}
</div>
)}
{this.props.showCommunity && (
<>
- <span class="mx-1">{i18n.t('to')}</span>
+ <span class="mx-1">{i18n.t("to")}</span>
<CommunityLink community={cv.community} />
<span class="mx-2">•</span>
<Link className="mr-2" to={`/post/${cv.post.id}`}>
class="btn btn-sm text-muted"
onClick={linkEvent(this, this.handleCommentCollapse)}
aria-label={
- this.state.collapsed ? i18n.t('expand') : i18n.t('collapse')
+ this.state.collapsed ? i18n.t("expand") : i18n.t("collapse")
}
>
- {this.state.collapsed ? '+' : '—'}
+ {this.state.collapsed ? "+" : "—"}
</button>
{/* This is an expanding spacer for mobile */}
<div className="mr-lg-4 flex-grow-1 flex-lg-grow-0 unselectable pointer mx-2"></div>
>
<span
class="mr-1 font-weight-bold"
- aria-label={i18n.t('number_of_points', {
+ aria-label={i18n.t("number_of_points", {
count: this.state.score,
})}
>
onClick={linkEvent(this, this.handleMarkRead)}
data-tippy-content={
this.commentOrMentionRead
- ? i18n.t('mark_as_unread')
- : i18n.t('mark_as_read')
+ ? i18n.t("mark_as_unread")
+ : i18n.t("mark_as_read")
}
aria-label={
this.commentOrMentionRead
- ? i18n.t('mark_as_unread')
- : i18n.t('mark_as_read')
+ ? i18n.t("mark_as_unread")
+ : i18n.t("mark_as_read")
}
>
{this.state.readLoading ? (
<Icon
icon="check"
classes={`icon-inline ${
- this.commentOrMentionRead && 'text-success'
+ this.commentOrMentionRead && "text-success"
}`}
/>
)}
<>
<button
className={`btn btn-link btn-animate ${
- this.state.my_vote == 1 ? 'text-info' : 'text-muted'
+ this.state.my_vote == 1 ? "text-info" : "text-muted"
}`}
onClick={linkEvent(node, this.handleCommentUpvote)}
- data-tippy-content={i18n.t('upvote')}
- aria-label={i18n.t('upvote')}
+ data-tippy-content={i18n.t("upvote")}
+ aria-label={i18n.t("upvote")}
>
<Icon icon="arrow-up1" classes="icon-inline" />
{this.state.upvotes !== this.state.score && (
<button
className={`btn btn-link btn-animate ${
this.state.my_vote == -1
- ? 'text-danger'
- : 'text-muted'
+ ? "text-danger"
+ : "text-muted"
}`}
onClick={linkEvent(node, this.handleCommentDownvote)}
- data-tippy-content={i18n.t('downvote')}
- aria-label={i18n.t('downvote')}
+ data-tippy-content={i18n.t("downvote")}
+ aria-label={i18n.t("downvote")}
>
<Icon icon="arrow-down1" classes="icon-inline" />
{this.state.upvotes !== this.state.score && (
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleReplyClick)}
- data-tippy-content={i18n.t('reply')}
- aria-label={i18n.t('reply')}
+ data-tippy-content={i18n.t("reply")}
+ aria-label={i18n.t("reply")}
>
<Icon icon="reply1" classes="icon-inline" />
</button>
<button
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleShowAdvanced)}
- data-tippy-content={i18n.t('more')}
- aria-label={i18n.t('more')}
+ data-tippy-content={i18n.t("more")}
+ aria-label={i18n.t("more")}
>
<Icon icon="more-vertical" classes="icon-inline" />
</button>
<Link
className="text-muted"
to={`/create_private_message/recipient/${cv.creator.id}`}
- title={i18n.t('message').toLowerCase()}
+ title={i18n.t("message").toLowerCase()}
>
<Icon icon="mail" />
</Link>
this.handleSaveCommentClick
)}
data-tippy-content={
- cv.saved ? i18n.t('unsave') : i18n.t('save')
+ cv.saved ? i18n.t("unsave") : i18n.t("save")
}
aria-label={
- cv.saved ? i18n.t('unsave') : i18n.t('save')
+ cv.saved ? i18n.t("unsave") : i18n.t("save")
}
>
{this.state.saveLoading ? (
<Icon
icon="star"
classes={`icon-inline ${
- cv.saved && 'text-warning'
+ cv.saved && "text-warning"
}`}
/>
)}
<button
className="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleViewSource)}
- data-tippy-content={i18n.t('view_source')}
- aria-label={i18n.t('view_source')}
+ data-tippy-content={i18n.t("view_source")}
+ aria-label={i18n.t("view_source")}
>
<Icon
icon="file-text"
classes={`icon-inline ${
- this.state.viewSource && 'text-success'
+ this.state.viewSource && "text-success"
}`}
/>
</button>
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleEditClick)}
- data-tippy-content={i18n.t('edit')}
- aria-label={i18n.t('edit')}
+ data-tippy-content={i18n.t("edit")}
+ aria-label={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
</button>
)}
data-tippy-content={
!cv.comment.deleted
- ? i18n.t('delete')
- : i18n.t('restore')
+ ? i18n.t("delete")
+ : i18n.t("restore")
}
aria-label={
!cv.comment.deleted
- ? i18n.t('delete')
- : i18n.t('restore')
+ ? i18n.t("delete")
+ : i18n.t("restore")
}
>
<Icon
icon="trash"
classes={`icon-inline ${
- cv.comment.deleted && 'text-danger'
+ cv.comment.deleted && "text-danger"
}`}
/>
</button>
this,
this.handleModRemoveShow
)}
- aria-label={i18n.t('remove')}
+ aria-label={i18n.t("remove")}
>
- {i18n.t('remove')}
+ {i18n.t("remove")}
</button>
) : (
<button
this,
this.handleModRemoveSubmit
)}
- aria-label={i18n.t('restore')}
+ aria-label={i18n.t("restore")}
>
- {i18n.t('restore')}
+ {i18n.t("restore")}
</button>
)}
</>
this,
this.handleModBanFromCommunityShow
)}
- aria-label={i18n.t('ban')}
+ aria-label={i18n.t("ban")}
>
- {i18n.t('ban')}
+ {i18n.t("ban")}
</button>
) : (
<button
this,
this.handleModBanFromCommunitySubmit
)}
- aria-label={i18n.t('unban')}
+ aria-label={i18n.t("unban")}
>
- {i18n.t('unban')}
+ {i18n.t("unban")}
</button>
))}
{!cv.creator_banned_from_community &&
)}
aria-label={
this.isMod
- ? i18n.t('remove_as_mod')
- : i18n.t('appoint_as_mod')
+ ? i18n.t("remove_as_mod")
+ : i18n.t("appoint_as_mod")
}
>
{this.isMod
- ? i18n.t('remove_as_mod')
- : i18n.t('appoint_as_mod')}
+ ? i18n.t("remove_as_mod")
+ : i18n.t("appoint_as_mod")}
</button>
) : (
<>
<button
class="btn btn-link btn-animate text-muted"
- aria-label={i18n.t('are_you_sure')}
+ aria-label={i18n.t("are_you_sure")}
>
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleAddModToCommunity
)}
- aria-label={i18n.t('yes')}
+ aria-label={i18n.t("yes")}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleCancelConfirmAppointAsMod
)}
- aria-label={i18n.t('no')}
+ aria-label={i18n.t("no")}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</button>
</>
))}
this,
this.handleShowConfirmTransferCommunity
)}
- aria-label={i18n.t('transfer_community')}
+ aria-label={i18n.t("transfer_community")}
>
- {i18n.t('transfer_community')}
+ {i18n.t("transfer_community")}
</button>
) : (
<>
<button
class="btn btn-link btn-animate text-muted"
- aria-label={i18n.t('are_you_sure')}
+ aria-label={i18n.t("are_you_sure")}
>
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleTransferCommunity
)}
- aria-label={i18n.t('yes')}
+ aria-label={i18n.t("yes")}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this
.handleCancelShowConfirmTransferCommunity
)}
- aria-label={i18n.t('no')}
+ aria-label={i18n.t("no")}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</button>
</>
))}
this,
this.handleModBanShow
)}
- aria-label={i18n.t('ban_from_site')}
+ aria-label={i18n.t("ban_from_site")}
>
- {i18n.t('ban_from_site')}
+ {i18n.t("ban_from_site")}
</button>
) : (
<button
this,
this.handleModBanSubmit
)}
- aria-label={i18n.t('unban_from_site')}
+ aria-label={i18n.t("unban_from_site")}
>
- {i18n.t('unban_from_site')}
+ {i18n.t("unban_from_site")}
</button>
))}
{!cv.creator.banned &&
)}
aria-label={
this.isAdmin
- ? i18n.t('remove_as_admin')
- : i18n.t('appoint_as_admin')
+ ? i18n.t("remove_as_admin")
+ : i18n.t("appoint_as_admin")
}
>
{this.isAdmin
- ? i18n.t('remove_as_admin')
- : i18n.t('appoint_as_admin')}
+ ? i18n.t("remove_as_admin")
+ : i18n.t("appoint_as_admin")}
</button>
) : (
<>
<button class="btn btn-link btn-animate text-muted">
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleAddAdmin
)}
- aria-label={i18n.t('yes')}
+ aria-label={i18n.t("yes")}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleCancelConfirmAppointAsAdmin
)}
- aria-label={i18n.t('no')}
+ aria-label={i18n.t("no")}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</button>
</>
))}
this,
this.handleShowConfirmTransferSite
)}
- aria-label={i18n.t('transfer_site')}
+ aria-label={i18n.t("transfer_site")}
>
- {i18n.t('transfer_site')}
+ {i18n.t("transfer_site")}
</button>
) : (
<>
<button
class="btn btn-link btn-animate text-muted"
- aria-label={i18n.t('are_you_sure')}
+ aria-label={i18n.t("are_you_sure")}
>
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleTransferSite
)}
- aria-label={i18n.t('yes')}
+ aria-label={i18n.t("yes")}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</button>
<button
class="btn btn-link btn-animate text-muted"
this,
this.handleCancelShowConfirmTransferSite
)}
- aria-label={i18n.t('no')}
+ aria-label={i18n.t("no")}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</button>
</>
))}
class="sr-only"
htmlFor={`mod-remove-reason-${cv.comment.id}`}
>
- {i18n.t('reason')}
+ {i18n.t("reason")}
</label>
<input
type="text"
id={`mod-remove-reason-${cv.comment.id}`}
class="form-control mr-2"
- placeholder={i18n.t('reason')}
+ placeholder={i18n.t("reason")}
value={this.state.removeReason}
onInput={linkEvent(this, this.handleModRemoveReasonChange)}
/>
<button
type="submit"
class="btn btn-secondary"
- aria-label={i18n.t('remove_comment')}
+ aria-label={i18n.t("remove_comment")}
>
- {i18n.t('remove_comment')}
+ {i18n.t("remove_comment")}
</button>
</form>
)}
class="col-form-label"
htmlFor={`mod-ban-reason-${cv.comment.id}`}
>
- {i18n.t('reason')}
+ {i18n.t("reason")}
</label>
<input
type="text"
id={`mod-ban-reason-${cv.comment.id}`}
class="form-control mr-2"
- placeholder={i18n.t('reason')}
+ placeholder={i18n.t("reason")}
value={this.state.banReason}
onInput={linkEvent(this, this.handleModBanReasonChange)}
/>
onChange={linkEvent(this, this.handleModRemoveDataChange)}
/>
<label class="form-check-label" htmlFor="mod-ban-remove-data">
- {i18n.t('remove_posts_comments')}
+ {i18n.t("remove_posts_comments")}
</label>
</div>
</div>
<button
type="submit"
class="btn btn-secondary"
- aria-label={i18n.t('ban')}
+ aria-label={i18n.t("ban")}
>
- {i18n.t('ban')} {cv.creator.name}
+ {i18n.t("ban")} {cv.creator.name}
</button>
</div>
</form>
<Link
className="btn btn-link btn-animate text-muted"
to={`/post/${cv.post.id}/comment/${cv.comment.id}`}
- title={this.props.showContext ? i18n.t('show_context') : i18n.t('link')}
+ title={this.props.showContext ? i18n.t("show_context") : i18n.t("link")}
>
<Icon icon="link" classes="icon-inline" />
</Link>
get commentUnlessRemoved(): string {
let comment = this.props.node.comment_view.comment;
return comment.removed
- ? `*${i18n.t('removed')}*`
+ ? `*${i18n.t("removed")}*`
: comment.deleted
- ? `*${i18n.t('deleted')}*`
+ ? `*${i18n.t("deleted")}*`
: comment.content;
}
}
get isCommentNew(): boolean {
- let now = moment.utc().subtract(10, 'minutes');
+ let now = moment.utc().subtract(10, "minutes");
let then = moment.utc(this.props.node.comment_view.comment.published);
return now.isBefore(then);
}
get scoreColor() {
if (this.state.my_vote == 1) {
- return 'text-info';
+ return "text-info";
} else if (this.state.my_vote == -1) {
- return 'text-danger';
+ return "text-danger";
} else {
- return 'text-muted';
+ return "text-muted";
}
}
get pointsTippy(): string {
- let points = i18n.t('number_of_points', {
+ let points = i18n.t("number_of_points", {
count: this.state.score,
});
- let upvotes = i18n.t('number_of_upvotes', {
+ let upvotes = i18n.t("number_of_upvotes", {
count: this.state.upvotes,
});
- let downvotes = i18n.t('number_of_downvotes', {
+ let downvotes = i18n.t("number_of_downvotes", {
count: this.state.downvotes,
});
-import { Component } from 'inferno';
-import { CommentNode as CommentNodeI } from '../interfaces';
-import { CommunityModeratorView, UserViewSafe } from 'lemmy-js-client';
-import { CommentNode } from './comment-node';
+import { Component } from "inferno";
+import { CommentNode as CommentNodeI } from "../interfaces";
+import { CommunityModeratorView, UserViewSafe } from "lemmy-js-client";
+import { CommentNode } from "./comment-node";
interface CommentNodesProps {
nodes: CommentNodeI[];
enableDownvotes: boolean;
}
-export class CommentNodes extends Component<
- CommentNodesProps,
- any
-> {
+export class CommentNodes extends Component<CommentNodesProps, any> {
constructor(props: any, context: any) {
super(props, context);
}
-import { Component, linkEvent } from 'inferno';
-import { HtmlTags } from './html-tags';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { HtmlTags } from "./html-tags";
+import { Subscription } from "rxjs";
import {
UserOperation,
CommunityView,
SortType,
ListingType,
SiteView,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
wsJsonToRes,
toast,
wsClient,
authField,
setOptionalAuth,
-} from '../utils';
-import { CommunityLink } from './community-link';
-import { Spinner } from './icon';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+} from "../utils";
+import { CommunityLink } from "./community-link";
+import { Spinner } from "./icon";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
const communityLimit = 100;
loading: true,
page: getPageFromProps(this.props),
site_view: this.isoData.site_res.site_view,
- searchText: '',
+ searchText: "",
};
constructor(props: any, context: any) {
}
get documentTitle(): string {
- return `${i18n.t('communities')} - ${this.state.site_view.site.name}`;
+ return `${i18n.t("communities")} - ${this.state.site_view.site.name}`;
}
render() {
<div>
<div class="row">
<div class="col-md-6">
- <h4>{i18n.t('list_of_communities')}</h4>
+ <h4>{i18n.t("list_of_communities")}</h4>
</div>
<div class="col-md-6">
<div class="float-md-right">{this.searchForm()}</div>
<table id="community_table" class="table table-sm table-hover">
<thead class="pointer">
<tr>
- <th>{i18n.t('name')}</th>
- <th>{i18n.t('category')}</th>
- <th class="text-right">{i18n.t('subscribers')}</th>
+ <th>{i18n.t("name")}</th>
+ <th>{i18n.t("category")}</th>
+ <th class="text-right">{i18n.t("subscribers")}</th>
<th class="text-right">
- {i18n.t('users')} / {i18n.t('month')}
+ {i18n.t("users")} / {i18n.t("month")}
</th>
<th class="text-right d-none d-lg-table-cell">
- {i18n.t('posts')}
+ {i18n.t("posts")}
</th>
<th class="text-right d-none d-lg-table-cell">
- {i18n.t('comments')}
+ {i18n.t("comments")}
</th>
<th></th>
</tr>
this.handleUnsubscribe
)}
>
- {i18n.t('unsubscribe')}
+ {i18n.t("unsubscribe")}
</span>
) : (
<span
this.handleSubscribe
)}
>
- {i18n.t('subscribe')}
+ {i18n.t("subscribe")}
</span>
)}
</td>
id="communities-search"
class="form-control mr-2 mb-2"
value={this.state.searchText}
- placeholder={`${i18n.t('search')}...`}
+ placeholder={`${i18n.t("search")}...`}
onInput={linkEvent(this, this.handleSearchChange)}
required
minLength={3}
/>
<label class="sr-only" htmlFor="communities-search">
- {i18n.t('search')}
+ {i18n.t("search")}
</label>
<button type="submit" class="btn btn-secondary mr-2 mb-2">
- <span>{i18n.t('search')}</span>
+ <span>{i18n.t("search")}</span>
</button>
</form>
);
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
)}
</div>
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let page = pathSplit[3] ? Number(pathSplit[3]) : 1;
let listCommunitiesForm: ListCommunities = {
type_: ListingType.All,
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (op == UserOperation.ListCommunities) {
let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
-import { Component, linkEvent } from 'inferno';
-import { Prompt } from 'inferno-router';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Prompt } from "inferno-router";
+import { Subscription } from "rxjs";
import {
EditCommunity,
CreateCommunity,
Category,
CommunityResponse,
CommunityView,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
wsJsonToRes,
capitalizeFirstLetter,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import { i18n } from '../i18next';
+} from "../utils";
+import { i18n } from "../i18next";
-import { MarkdownTextArea } from './markdown-textarea';
-import { ImageUploadForm } from './image-upload-form';
-import { Icon, Spinner } from './icon';
+import { MarkdownTextArea } from "./markdown-textarea";
+import { ImageUploadForm } from "./image-upload-form";
+import { Icon, Spinner } from "./icon";
interface CommunityFormProps {
community_view?: CommunityView; // If a community is given, that means this is an edit
this.state.communityForm.title ||
this.state.communityForm.description)
}
- message={i18n.t('block_leaving')}
+ message={i18n.t("block_leaving")}
/>
<form onSubmit={linkEvent(this, this.handleCreateCommunitySubmit)}>
{!this.props.community_view && (
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor="community-name">
- {i18n.t('name')}
+ {i18n.t("name")}
<span
class="pointer unselectable ml-2 text-muted"
- data-tippy-content={i18n.t('name_explain')}
+ data-tippy-content={i18n.t("name_explain")}
>
<Icon icon="help-circle" classes="icon-inline" />
</span>
minLength={3}
maxLength={20}
pattern="[a-z0-9_]+"
- title={i18n.t('community_reqs')}
+ title={i18n.t("community_reqs")}
/>
</div>
</div>
)}
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor="community-title">
- {i18n.t('display_name')}
+ {i18n.t("display_name")}
<span
class="pointer unselectable ml-2 text-muted"
- data-tippy-content={i18n.t('display_name_explain')}
+ data-tippy-content={i18n.t("display_name_explain")}
>
<Icon icon="help-circle" classes="icon-inline" />
</span>
</div>
</div>
<div class="form-group">
- <label>{i18n.t('icon')}</label>
+ <label>{i18n.t("icon")}</label>
<ImageUploadForm
- uploadTitle={i18n.t('upload_icon')}
+ uploadTitle={i18n.t("upload_icon")}
imageSrc={this.state.communityForm.icon}
onUpload={this.handleIconUpload}
onRemove={this.handleIconRemove}
/>
</div>
<div class="form-group">
- <label>{i18n.t('banner')}</label>
+ <label>{i18n.t("banner")}</label>
<ImageUploadForm
- uploadTitle={i18n.t('upload_banner')}
+ uploadTitle={i18n.t("upload_banner")}
imageSrc={this.state.communityForm.banner}
onUpload={this.handleBannerUpload}
onRemove={this.handleBannerRemove}
</div>
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor={this.id}>
- {i18n.t('sidebar')}
+ {i18n.t("sidebar")}
</label>
<div class="col-12">
<MarkdownTextArea
</div>
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor="community-category">
- {i18n.t('category')}
+ {i18n.t("category")}
</label>
<div class="col-12">
<select
onChange={linkEvent(this, this.handleCommunityNsfwChange)}
/>
<label class="form-check-label" htmlFor="community-nsfw">
- {i18n.t('nsfw')}
+ {i18n.t("nsfw")}
</label>
</div>
</div>
{this.state.loading ? (
<Spinner />
) : this.props.community_view ? (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
) : (
- capitalizeFirstLetter(i18n.t('create'))
+ capitalizeFirstLetter(i18n.t("create"))
)}
</button>
{this.props.community_view && (
class="btn btn-secondary"
onClick={linkEvent(this, this.handleCancel)}
>
- {i18n.t('cancel')}
+ {i18n.t("cancel")}
</button>
)}
</div>
}
handleIconRemove() {
- this.state.communityForm.icon = '';
+ this.state.communityForm.icon = "";
this.setState(this.state);
}
}
handleBannerRemove() {
- this.state.communityForm.banner = '';
+ this.state.communityForm.banner = "";
this.setState(this.state);
}
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state.loading = false;
this.setState(this.state);
return;
-import { Component } from 'inferno';
-import { Link } from 'inferno-router';
-import { CommunitySafe } from 'lemmy-js-client';
-import { hostname, showAvatars } from '../utils';
-import { PictrsImage } from './pictrs-image';
+import { Component } from "inferno";
+import { Link } from "inferno-router";
+import { CommunitySafe } from "lemmy-js-client";
+import { hostname, showAvatars } from "../utils";
+import { PictrsImage } from "./pictrs-image";
interface CommunityLinkProps {
// TODO figure this out better
return (
<Link
title={apubName}
- className={`${this.props.muted ? 'text-muted' : ''}`}
+ className={`${this.props.muted ? "text-muted" : ""}`}
to={link}
>
{!this.props.hideAvatar && community.icon && showAvatars() && (
-import { Component, linkEvent } from 'inferno';
-import { Subscription } from 'rxjs';
-import { DataType, InitialFetchRequest } from '../interfaces';
+import { Component, linkEvent } from "inferno";
+import { Subscription } from "rxjs";
+import { DataType, InitialFetchRequest } from "../interfaces";
import {
UserOperation,
GetCommunityResponse,
GetSiteResponse,
Category,
ListCategoriesResponse,
-} from 'lemmy-js-client';
-import { UserService, WebSocketService } from '../services';
-import { PostListings } from './post-listings';
-import { CommentNodes } from './comment-nodes';
-import { HtmlTags } from './html-tags';
-import { SortSelect } from './sort-select';
-import { DataTypeSelect } from './data-type-select';
-import { Sidebar } from './sidebar';
-import { CommunityLink } from './community-link';
-import { BannerIconHeader } from './banner-icon-header';
-import { Icon, Spinner } from './icon';
+} from "lemmy-js-client";
+import { UserService, WebSocketService } from "../services";
+import { PostListings } from "./post-listings";
+import { CommentNodes } from "./comment-nodes";
+import { HtmlTags } from "./html-tags";
+import { SortSelect } from "./sort-select";
+import { DataTypeSelect } from "./data-type-select";
+import { Sidebar } from "./sidebar";
+import { CommunityLink } from "./community-link";
+import { BannerIconHeader } from "./banner-icon-header";
+import { Icon, Spinner } from "./icon";
import {
wsJsonToRes,
fetchLimit,
setOptionalAuth,
saveScrollPosition,
restoreScrollPosition,
-} from '../utils';
-import { i18n } from '../i18next';
+} from "../utils";
+import { i18n } from "../i18next";
interface State {
communityRes: GetCommunityResponse;
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let promises: Promise<any>[] = [];
// It can be /c/main, or /c/1
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
{this.state.posts.length > 0 && (
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
)}
</div>
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
- this.context.router.history.push('/');
+ toast(i18n.t(msg.error), "danger");
+ this.context.router.history.push("/");
return;
} else if (msg.reconnect) {
WebSocketService.Instance.send(
-import { Component } from 'inferno';
-import { Subscription } from 'rxjs';
-import { CommunityForm } from './community-form';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
+import { Component } from "inferno";
+import { Subscription } from "rxjs";
+import { CommunityForm } from "./community-form";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
import {
CommunityView,
UserOperation,
SiteView,
ListCategoriesResponse,
Category,
-} from 'lemmy-js-client';
+} from "lemmy-js-client";
import {
setIsoData,
toast,
isBrowser,
wsUserOp,
wsClient,
-} from '../utils';
-import { WebSocketService, UserService } from '../services';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+} from "../utils";
+import { WebSocketService, UserService } from "../services";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
interface CreateCommunityState {
site_view: SiteView;
this.subscription = wsSubscribe(this.parseMessage);
if (!UserService.Instance.user && isBrowser()) {
- toast(i18n.t('not_logged_in'), 'danger');
+ toast(i18n.t("not_logged_in"), "danger");
this.context.router.history.push(`/login`);
}
}
get documentTitle(): string {
- return `${i18n.t('create_community')} - ${this.state.site_view.site.name}`;
+ return `${i18n.t("create_community")} - ${this.state.site_view.site.name}`;
}
render() {
) : (
<div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>{i18n.t('create_community')}</h5>
+ <h5>{i18n.t("create_community")}</h5>
<CommunityForm
categories={this.state.categories}
onCreate={this.handleCommunityCreate}
-import { Component } from 'inferno';
-import { Subscription } from 'rxjs';
-import { PostForm } from './post-form';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
+import { Component } from "inferno";
+import { Subscription } from "rxjs";
+import { PostForm } from "./post-form";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
import {
authField,
isBrowser,
wsJsonToRes,
wsSubscribe,
wsUserOp,
-} from '../utils';
-import { UserService, WebSocketService } from '../services';
+} from "../utils";
+import { UserService, WebSocketService } from "../services";
import {
UserOperation,
ListCommunitiesResponse,
SortType,
ListingType,
PostView,
-} from 'lemmy-js-client';
-import { i18n } from '../i18next';
-import { InitialFetchRequest, PostFormParams } from 'shared/interfaces';
+} from "lemmy-js-client";
+import { i18n } from "../i18next";
+import { InitialFetchRequest, PostFormParams } from "shared/interfaces";
interface CreatePostState {
site_view: SiteView;
this.state = this.emptyState;
if (!UserService.Instance.user && isBrowser()) {
- toast(i18n.t('not_logged_in'), 'danger');
+ toast(i18n.t("not_logged_in"), "danger");
this.context.router.history.push(`/login`);
}
}
get documentTitle(): string {
- return `${i18n.t('create_post')} - ${this.state.site_view.site.name}`;
+ return `${i18n.t("create_post")} - ${this.state.site_view.site.name}`;
}
render() {
) : (
<div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>{i18n.t('create_post')}</h5>
+ <h5>{i18n.t("create_post")}</h5>
<PostForm
communities={this.state.communities}
onCreate={this.handlePostCreate}
get params(): PostFormParams {
let urlParams = new URLSearchParams(this.props.location.search);
let params: PostFormParams = {
- name: urlParams.get('title'),
- community_name: urlParams.get('community_name') || this.prevCommunityName,
- community_id: urlParams.get('community_id')
- ? Number(urlParams.get('community_id')) || this.prevCommunityId
+ name: urlParams.get("title"),
+ community_name: urlParams.get("community_name") || this.prevCommunityName,
+ community_id: urlParams.get("community_id")
+ ? Number(urlParams.get("community_id")) || this.prevCommunityId
: null,
- body: urlParams.get('body'),
- url: urlParams.get('url'),
+ body: urlParams.get("body"),
+ url: urlParams.get("url"),
};
return params;
return this.props.match.params.name;
} else if (this.props.location.state) {
let lastLocation = this.props.location.state.prevPath;
- if (lastLocation.includes('/c/')) {
- return lastLocation.split('/c/')[1];
+ if (lastLocation.includes("/c/")) {
+ return lastLocation.split("/c/")[1];
}
}
return null;
return this.props.match.params.id;
} else if (this.props.location.state) {
let lastLocation = this.props.location.state.prevPath;
- if (lastLocation.includes('/community/')) {
- return Number(lastLocation.split('/community/')[1]);
+ if (lastLocation.includes("/community/")) {
+ return Number(lastLocation.split("/community/")[1]);
}
}
return null;
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (op == UserOperation.ListCommunities) {
let data = wsJsonToRes<ListCommunitiesResponse>(msg).data;
-import { Component } from 'inferno';
-import { Subscription } from 'rxjs';
-import { PrivateMessageForm } from './private-message-form';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
-import { UserService, WebSocketService } from '../services';
+import { Component } from "inferno";
+import { Subscription } from "rxjs";
+import { PrivateMessageForm } from "./private-message-form";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
+import { UserService, WebSocketService } from "../services";
import {
SiteView,
UserOperation,
UserViewSafe,
SortType,
GetUserDetails,
-} from 'lemmy-js-client';
+} from "lemmy-js-client";
import {
authField,
getRecipientIdFromProps,
wsJsonToRes,
wsSubscribe,
wsUserOp,
-} from '../utils';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+} from "../utils";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
interface CreatePrivateMessageState {
site_view: SiteView;
this.subscription = wsSubscribe(this.parseMessage);
if (!UserService.Instance.user) {
- toast(i18n.t('not_logged_in'), 'danger');
+ toast(i18n.t("not_logged_in"), "danger");
this.context.router.history.push(`/login`);
}
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let user_id = Number(req.path.split('/').pop());
+ let user_id = Number(req.path.split("/").pop());
let form: GetUserDetails = {
user_id,
sort: SortType.New,
}
get documentTitle(): string {
- return `${i18n.t('create_private_message')} - ${
+ return `${i18n.t("create_private_message")} - ${
this.state.site_view.site.name
}`;
}
) : (
<div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>{i18n.t('create_private_message')}</h5>
+ <h5>{i18n.t("create_private_message")}</h5>
<PrivateMessageForm
onCreate={this.handlePrivateMessageCreate}
recipient={this.state.recipient.user}
}
handlePrivateMessageCreate() {
- toast(i18n.t('message_sent'));
+ toast(i18n.t("message_sent"));
// Navigate to the front
this.context.router.history.push(`/`);
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state.loading = false;
this.setState(this.state);
return;
-import { Component, linkEvent } from 'inferno';
-import { DataType } from '../interfaces';
+import { Component, linkEvent } from "inferno";
+import { DataType } from "../interfaces";
-import { i18n } from '../i18next';
+import { i18n } from "../i18next";
interface DataTypeSelectProps {
type_: DataType;
<div class="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`pointer btn btn-outline-secondary
- ${this.state.type_ == DataType.Post && 'active'}
+ ${this.state.type_ == DataType.Post && "active"}
`}
>
<input
checked={this.state.type_ == DataType.Post}
onChange={linkEvent(this, this.handleTypeChange)}
/>
- {i18n.t('posts')}
+ {i18n.t("posts")}
</label>
<label
className={`pointer btn btn-outline-secondary ${
- this.state.type_ == DataType.Comment && 'active'
+ this.state.type_ == DataType.Comment && "active"
}`}
>
<input
checked={this.state.type_ == DataType.Comment}
onChange={linkEvent(this, this.handleTypeChange)}
/>
- {i18n.t('comments')}
+ {i18n.t("comments")}
</label>
</div>
);
-import { Component } from 'inferno';
-import { Link } from 'inferno-router';
-import { i18n } from '../i18next';
-import { repoUrl, joinLemmyUrl, docsUrl } from '../utils';
-import { GetSiteResponse } from 'lemmy-js-client';
+import { Component } from "inferno";
+import { Link } from "inferno-router";
+import { i18n } from "../i18next";
+import { repoUrl, joinLemmyUrl, docsUrl } from "../utils";
+import { GetSiteResponse } from "lemmy-js-client";
interface FooterProps {
site: GetSiteResponse;
</li>
<li className="nav-item">
<Link className="nav-link" to="/modlog">
- {i18n.t('modlog')}
+ {i18n.t("modlog")}
</Link>
</li>
{this.props.site.federated_instances && (
<li class="nav-item">
<Link className="nav-link" to="/instances">
- {i18n.t('instances')}
+ {i18n.t("instances")}
</Link>
</li>
)}
<li class="nav-item">
<a className="nav-link" href={docsUrl}>
- {i18n.t('docs')}
+ {i18n.t("docs")}
</a>
</li>
<li class="nav-item">
<a className="nav-link" href={repoUrl}>
- {i18n.t('code')}
+ {i18n.t("code")}
</a>
</li>
<li class="nav-item">
<a className="nav-link" href={joinLemmyUrl}>
- {i18n.t('join_lemmy')}
+ {i18n.t("join_lemmy")}
</a>
</li>
</ul>
-import { Component } from 'inferno';
-import { Helmet } from 'inferno-helmet';
-import { httpExternalPath } from '../env';
-import { md } from '../utils';
+import { Component } from "inferno";
+import { Helmet } from "inferno-helmet";
+import { httpExternalPath } from "../env";
+import { md } from "../utils";
interface HtmlTagsProps {
title: string;
return (
<Helmet title={this.props.title}>
- {['title', 'og:title', 'twitter:title'].map(t => (
+ {["title", "og:title", "twitter:title"].map(t => (
<meta property={t} content={this.props.title} />
))}
- {['og:url', 'twitter:url'].map(u => (
+ {["og:url", "twitter:url"].map(u => (
<meta property={u} content={url} />
))}
{/* Optional desc and images */}
{this.props.description &&
- ['description', 'og:description', 'twitter:description'].map(n => (
+ ["description", "og:description", "twitter:description"].map(n => (
<meta name={n} content={md.renderInline(this.props.description)} />
))}
{this.props.image &&
- ['og:image', 'twitter:image'].map(p => (
+ ["og:image", "twitter:image"].map(p => (
<meta property={p} content={this.props.image} />
))}
</Helmet>
-import { Component } from 'inferno';
+import { Component } from "inferno";
interface IconProps {
icon: string;
-import { Component, linkEvent } from 'inferno';
-import { Post } from 'lemmy-js-client';
-import { mdToHtml } from '../utils';
-import { i18n } from '../i18next';
-import { Icon } from './icon';
+import { Component, linkEvent } from "inferno";
+import { Post } from "lemmy-js-client";
+import { mdToHtml } from "../utils";
+import { i18n } from "../i18next";
+import { Icon } from "./icon";
interface FramelyCardProps {
post: Post;
<button
class="mt-2 btn btn-secondary text-monospace"
onClick={linkEvent(this, this.handleIframeExpand)}
- data-tippy-content={i18n.t('expand_here')}
+ data-tippy-content={i18n.t("expand_here")}
>
- {this.state.expanded ? '-' : '+'}
+ {this.state.expanded ? "-" : "+"}
</button>
)}
</div>
-import { Component, linkEvent } from 'inferno';
-import { pictrsUri } from '../env';
-import { UserService } from '../services';
-import { toast, randomStr } from '../utils';
-import { i18n } from '../i18next';
-import { Icon } from './icon';
+import { Component, linkEvent } from "inferno";
+import { pictrsUri } from "../env";
+import { UserService } from "../services";
+import { toast, randomStr } from "../utils";
+import { i18n } from "../i18next";
+import { Icon } from "./icon";
interface ImageUploadFormProps {
uploadTitle: string;
<span class="d-inline-block position-relative">
<img
src={this.props.imageSrc}
- height={this.props.rounded ? 60 : ''}
- width={this.props.rounded ? 60 : ''}
+ height={this.props.rounded ? 60 : ""}
+ width={this.props.rounded ? 60 : ""}
className={`img-fluid ${
- this.props.rounded ? 'rounded-circle' : ''
+ this.props.rounded ? "rounded-circle" : ""
}`}
/>
<a
onClick={linkEvent(this, this.handleRemoveImage)}
- aria-label={i18n.t('remove')}
+ aria-label={i18n.t("remove")}
>
<Icon icon="x" classes="mini-overlay" />
</a>
event.preventDefault();
let file = event.target.files[0];
const formData = new FormData();
- formData.append('images[]', file);
+ formData.append("images[]", file);
i.state.loading = true;
i.setState(i.state);
fetch(pictrsUri, {
- method: 'POST',
+ method: "POST",
body: formData,
})
.then(res => res.json())
.then(res => {
- console.log('pictrs upload:');
+ console.log("pictrs upload:");
console.log(res);
- if (res.msg == 'ok') {
+ if (res.msg == "ok") {
let hash = res.files[0].file;
let url = `${pictrsUri}/${hash}`;
i.state.loading = false;
} else {
i.state.loading = false;
i.setState(i.state);
- toast(JSON.stringify(res), 'danger');
+ toast(JSON.stringify(res), "danger");
}
})
.catch(error => {
i.state.loading = false;
i.setState(i.state);
- toast(error, 'danger');
+ toast(error, "danger");
});
}
-import { Component, linkEvent } from 'inferno';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Subscription } from "rxjs";
import {
UserOperation,
CommentView,
PrivateMessageResponse,
SiteView,
UserMentionView,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
import {
wsJsonToRes,
fetchLimit,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import { CommentNodes } from './comment-nodes';
-import { PrivateMessage } from './private-message';
-import { HtmlTags } from './html-tags';
-import { SortSelect } from './sort-select';
-import { Icon, Spinner } from './icon';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+} from "../utils";
+import { CommentNodes } from "./comment-nodes";
+import { PrivateMessage } from "./private-message";
+import { HtmlTags } from "./html-tags";
+import { SortSelect } from "./sort-select";
+import { Icon, Spinner } from "./icon";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
enum UnreadOrAll {
Unread,
this.handleSortChange = this.handleSortChange.bind(this);
if (!UserService.Instance.user && isBrowser()) {
- toast(i18n.t('not_logged_in'), 'danger');
+ toast(i18n.t("not_logged_in"), "danger");
this.context.router.history.push(`/login`);
}
}
get documentTitle(): string {
- return `@${UserService.Instance.user.name} ${i18n.t('inbox')} - ${
+ return `@${UserService.Instance.user.name} ${i18n.t("inbox")} - ${
this.state.site_view.site.name
}`;
}
path={this.context.router.route.match.url}
/>
<h5 class="mb-1">
- {i18n.t('inbox')}
+ {i18n.t("inbox")}
<small>
<a
href={`/feeds/inbox/${UserService.Instance.auth}.xml`}
role="button"
onClick={linkEvent(this, this.markAllAsRead)}
>
- {i18n.t('mark_all_as_read')}
+ {i18n.t("mark_all_as_read")}
</span>
</li>
</ul>
<div class="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary pointer
- ${this.state.unreadOrAll == UnreadOrAll.Unread && 'active'}
+ ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
`}
>
<input
checked={this.state.unreadOrAll == UnreadOrAll.Unread}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
- {i18n.t('unread')}
+ {i18n.t("unread")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.unreadOrAll == UnreadOrAll.All && 'active'}
+ ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
`}
>
<input
checked={this.state.unreadOrAll == UnreadOrAll.All}
onChange={linkEvent(this, this.handleUnreadOrAllChange)}
/>
- {i18n.t('all')}
+ {i18n.t("all")}
</label>
</div>
);
<div class="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary pointer
- ${this.state.messageType == MessageType.All && 'active'}
+ ${this.state.messageType == MessageType.All && "active"}
`}
>
<input
checked={this.state.messageType == MessageType.All}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t('all')}
+ {i18n.t("all")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.messageType == MessageType.Replies && 'active'}
+ ${this.state.messageType == MessageType.Replies && "active"}
`}
>
<input
checked={this.state.messageType == MessageType.Replies}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t('replies')}
+ {i18n.t("replies")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.messageType == MessageType.Mentions && 'active'}
+ ${this.state.messageType == MessageType.Mentions && "active"}
`}
>
<input
checked={this.state.messageType == MessageType.Mentions}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t('mentions')}
+ {i18n.t("mentions")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.messageType == MessageType.Messages && 'active'}
+ ${this.state.messageType == MessageType.Messages && "active"}
`}
>
<input
checked={this.state.messageType == MessageType.Messages}
onChange={linkEvent(this, this.handleMessageTypeChange)}
/>
- {i18n.t('messages')}
+ {i18n.t("messages")}
</label>
</div>
);
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
{this.unreadCount() > 0 && (
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
)}
</div>
let op = wsUserOp(msg);
console.log(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (msg.reconnect) {
this.refetch();
this.setState(this.state);
} else if (data.comment_view.creator.id == UserService.Instance.user.id) {
// TODO this seems wrong, you should be using form_id
- toast(i18n.t('reply_sent'));
+ toast(i18n.t("reply_sent"));
}
} else if (op == UserOperation.CreatePrivateMessage) {
let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
-import { Component } from 'inferno';
-import { GetSiteResponse } from 'lemmy-js-client';
-import { setIsoData } from '../utils';
-import { i18n } from '../i18next';
-import { HtmlTags } from './html-tags';
+import { Component } from "inferno";
+import { GetSiteResponse } from "lemmy-js-client";
+import { setIsoData } from "../utils";
+import { i18n } from "../i18next";
+import { HtmlTags } from "./html-tags";
interface InstancesState {
siteRes: GetSiteResponse;
}
get documentTitle(): string {
- return `${i18n.t('instances')} - ${this.state.siteRes.site_view.site.name}`;
+ return `${i18n.t("instances")} - ${this.state.siteRes.site_view.site.name}`;
}
render() {
/>
<div class="row">
<div class="col-md-6">
- <h5>{i18n.t('linked_instances')}</h5>
+ <h5>{i18n.t("linked_instances")}</h5>
{this.itemList(federated_instances.linked)}
</div>
{federated_instances.allowed.length > 0 && (
<div class="col-md-6">
- <h5>{i18n.t('allowed_instances')}</h5>
+ <h5>{i18n.t("allowed_instances")}</h5>
{this.itemList(federated_instances.allowed)}
</div>
)}
{federated_instances.blocked.length > 0 && (
<div class="col-md-6">
- <h5>{i18n.t('blocked_instances')}</h5>
+ <h5>{i18n.t("blocked_instances")}</h5>
{this.itemList(federated_instances.blocked)}
</div>
)}
))}
</ul>
) : (
- <div>{i18n.t('none_found')}</div>
+ <div>{i18n.t("none_found")}</div>
);
}
}
-import { Component, linkEvent } from 'inferno';
-import { ListingType } from 'lemmy-js-client';
-import { UserService } from '../services';
-import { randomStr } from '../utils';
-import { i18n } from '../i18next';
+import { Component, linkEvent } from "inferno";
+import { ListingType } from "lemmy-js-client";
+import { UserService } from "../services";
+import { randomStr } from "../utils";
+import { i18n } from "../i18next";
interface ListingTypeSelectProps {
type_: ListingType;
<div class="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary
- ${this.state.type_ == ListingType.Subscribed && 'active'}
- ${UserService.Instance.user == undefined ? 'disabled' : 'pointer'}
+ ${this.state.type_ == ListingType.Subscribed && "active"}
+ ${UserService.Instance.user == undefined ? "disabled" : "pointer"}
`}
>
<input
onChange={linkEvent(this, this.handleTypeChange)}
disabled={UserService.Instance.user == undefined}
/>
- {i18n.t('subscribed')}
+ {i18n.t("subscribed")}
</label>
{this.props.showLocal && (
<label
className={`pointer btn btn-outline-secondary ${
- this.state.type_ == ListingType.Local && 'active'
+ this.state.type_ == ListingType.Local && "active"
}`}
>
<input
checked={this.state.type_ == ListingType.Local}
onChange={linkEvent(this, this.handleTypeChange)}
/>
- {i18n.t('local')}
+ {i18n.t("local")}
</label>
)}
<label
className={`pointer btn btn-outline-secondary ${
- (this.state.type_ == ListingType.All && 'active') ||
+ (this.state.type_ == ListingType.All && "active") ||
(!this.props.showLocal &&
this.state.type_ == ListingType.Local &&
- 'active')
+ "active")
}`}
>
<input
checked={this.state.type_ == ListingType.All}
onChange={linkEvent(this, this.handleTypeChange)}
/>
- {i18n.t('all')}
+ {i18n.t("all")}
</label>
</div>
);
-import { Component, linkEvent } from 'inferno';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Subscription } from "rxjs";
import {
Login as LoginForm,
Register,
GetSiteResponse,
GetCaptchaResponse,
SiteView,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
import {
wsJsonToRes,
validEmail,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import { i18n } from '../i18next';
-import { HtmlTags } from './html-tags';
-import { Icon, Spinner } from './icon';
+} from "../utils";
+import { i18n } from "../i18next";
+import { HtmlTags } from "./html-tags";
+import { Icon, Spinner } from "./icon";
interface State {
loginForm: LoginForm;
}
get documentTitle(): string {
- return `${i18n.t('login')} - ${this.state.site_view.site.name}`;
+ return `${i18n.t("login")} - ${this.state.site_view.site.name}`;
}
render() {
return (
<div>
<form onSubmit={linkEvent(this, this.handleLoginSubmit)}>
- <h5>{i18n.t('login')}</h5>
+ <h5>{i18n.t("login")}</h5>
<div class="form-group row">
<label
class="col-sm-2 col-form-label"
htmlFor="login-email-or-username"
>
- {i18n.t('email_or_username')}
+ {i18n.t("email_or_username")}
</label>
<div class="col-sm-10">
<input
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="login-password">
- {i18n.t('password')}
+ {i18n.t("password")}
</label>
<div class="col-sm-10">
<input
onClick={linkEvent(this, this.handlePasswordReset)}
className="btn p-0 btn-link d-inline-block float-right text-muted small font-weight-bold pointer-events"
disabled={!validEmail(this.state.loginForm.username_or_email)}
- title={i18n.t('no_password_reset')}
+ title={i18n.t("no_password_reset")}
>
- {i18n.t('forgot_password')}
+ {i18n.t("forgot_password")}
</button>
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-secondary">
- {this.state.loginLoading ? <Spinner /> : i18n.t('login')}
+ {this.state.loginLoading ? <Spinner /> : i18n.t("login")}
</button>
</div>
</div>
registerForm() {
return (
<form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
- <h5>{i18n.t('sign_up')}</h5>
+ <h5>{i18n.t("sign_up")}</h5>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="register-username">
- {i18n.t('username')}
+ {i18n.t("username")}
</label>
<div class="col-sm-10">
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="register-email">
- {i18n.t('email')}
+ {i18n.t("email")}
</label>
<div class="col-sm-10">
<input
type="email"
id="register-email"
class="form-control"
- placeholder={i18n.t('optional')}
+ placeholder={i18n.t("optional")}
value={this.state.registerForm.email}
onInput={linkEvent(this, this.handleRegisterEmailChange)}
minLength={3}
{!validEmail(this.state.registerForm.email) && (
<div class="mt-2 mb-0 alert alert-light" role="alert">
<Icon icon="alert-triangle" classes="icon-inline mr-2" />
- {i18n.t('no_password_reset')}
+ {i18n.t("no_password_reset")}
</div>
)}
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="register-password">
- {i18n.t('password')}
+ {i18n.t("password")}
</label>
<div class="col-sm-10">
<input
class="col-sm-2 col-form-label"
htmlFor="register-verify-password"
>
- {i18n.t('verify_password')}
+ {i18n.t("verify_password")}
</label>
<div class="col-sm-10">
<input
{this.state.captcha && (
<div class="form-group row">
<label class="col-sm-2" htmlFor="register-captcha">
- <span class="mr-2">{i18n.t('enter_code')}</span>
+ <span class="mr-2">{i18n.t("enter_code")}</span>
<button
type="button"
class="btn btn-secondary"
onClick={linkEvent(this, this.handleRegenCaptcha)}
- aria-label={i18n.t('captcha')}
+ aria-label={i18n.t("captcha")}
>
<Icon icon="refresh-cw" classes="icon-refresh-cw" />
</button>
onChange={linkEvent(this, this.handleRegisterShowNsfwChange)}
/>
<label class="form-check-label" htmlFor="register-show-nsfw">
- {i18n.t('show_nsfw')}
+ {i18n.t("show_nsfw")}
</label>
</div>
</div>
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-secondary">
- {this.state.registerLoading ? <Spinner /> : i18n.t('sign_up')}
+ {this.state.registerLoading ? <Spinner /> : i18n.t("sign_up")}
</button>
</div>
</div>
class="rounded-top img-fluid"
src={this.captchaPngSrc()}
style="border-bottom-right-radius: 0; border-bottom-left-radius: 0;"
- alt={i18n.t('captcha')}
+ alt={i18n.t("captcha")}
/>
{this.state.captcha.ok.wav && (
<button
class="rounded-bottom btn btn-sm btn-secondary btn-block"
style="border-top-right-radius: 0; border-top-left-radius: 0;"
- title={i18n.t('play_captcha_audio')}
+ title={i18n.t("play_captcha_audio")}
onClick={linkEvent(this, this.handleCaptchaPlay)}
type="button"
disabled={this.state.captchaPlaying}
handleRegisterEmailChange(i: Login, event: any) {
i.state.registerForm.email = event.target.value;
- if (i.state.registerForm.email == '') {
+ if (i.state.registerForm.email == "") {
i.state.registerForm.email = undefined;
}
i.setState(i.state);
handleCaptchaPlay(i: Login, event: any) {
event.preventDefault();
- let snd = new Audio('data:audio/wav;base64,' + i.state.captcha.ok.wav);
+ let snd = new Audio("data:audio/wav;base64," + i.state.captcha.ok.wav);
snd.play();
i.state.captchaPlaying = true;
i.setState(i.state);
- snd.addEventListener('ended', () => {
+ snd.addEventListener("ended", () => {
snd.currentTime = 0;
i.state.captchaPlaying = false;
i.setState(this.state);
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state = this.emptyState;
this.state.registerForm.captcha_answer = undefined;
// Refetch another captcha
auth: authField(),
})
);
- toast(i18n.t('logged_in'));
- this.props.history.push('/');
+ toast(i18n.t("logged_in"));
+ this.props.history.push("/");
} else if (op == UserOperation.Register) {
let data = wsJsonToRes<LoginResponse>(msg).data;
this.state = this.emptyState;
auth: authField(),
})
);
- this.props.history.push('/communities');
+ this.props.history.push("/communities");
} else if (op == UserOperation.GetCaptcha) {
let data = wsJsonToRes<GetCaptchaResponse>(msg).data;
if (data.ok) {
this.setState(this.state);
}
} else if (op == UserOperation.PasswordReset) {
- toast(i18n.t('reset_password_mail_sent'));
+ toast(i18n.t("reset_password_mail_sent"));
} else if (op == UserOperation.GetSite) {
let data = wsJsonToRes<GetSiteResponse>(msg).data;
this.state.site_view = data.site_view;
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
+import { Subscription } from "rxjs";
import {
UserOperation,
CommunityFollowerView,
CommentResponse,
AddAdminResponse,
BanUserResponse,
-} from 'lemmy-js-client';
-import { DataType, InitialFetchRequest } from '../interfaces';
-import { WebSocketService, UserService } from '../services';
-import { PostListings } from './post-listings';
-import { CommentNodes } from './comment-nodes';
-import { SortSelect } from './sort-select';
-import { ListingTypeSelect } from './listing-type-select';
-import { DataTypeSelect } from './data-type-select';
-import { SiteForm } from './site-form';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { BannerIconHeader } from './banner-icon-header';
-import { Icon, Spinner } from './icon';
+} from "lemmy-js-client";
+import { DataType, InitialFetchRequest } from "../interfaces";
+import { WebSocketService, UserService } from "../services";
+import { PostListings } from "./post-listings";
+import { CommentNodes } from "./comment-nodes";
+import { SortSelect } from "./sort-select";
+import { ListingTypeSelect } from "./listing-type-select";
+import { DataTypeSelect } from "./data-type-select";
+import { SiteForm } from "./site-form";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { BannerIconHeader } from "./banner-icon-header";
+import { Icon, Spinner } from "./icon";
import {
wsJsonToRes,
mdToHtml,
authField,
saveScrollPosition,
restoreScrollPosition,
-} from '../utils';
-import { i18n } from '../i18next';
-import { T } from 'inferno-i18next';
-import { HtmlTags } from './html-tags';
+} from "../utils";
+import { i18n } from "../i18next";
+import { T } from "inferno-i18next";
+import { HtmlTags } from "./html-tags";
interface MainState {
subscribedCommunities: CommunityFollowerView[];
componentDidMount() {
// This means it hasn't been set up yet
if (!this.state.siteRes.site_view) {
- this.context.router.history.push('/setup');
+ this.context.router.history.push("/setup");
}
WebSocketService.Instance.send(wsClient.communityJoin({ community_id: 0 }));
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let dataType: DataType = pathSplit[3]
? DataType[pathSplit[3]]
: DataType.Post;
return `${
this.state.siteRes.site_view
? this.state.siteRes.site_view.site.name
- : 'Lemmy'
+ : "Lemmy"
}`;
}
createCommunityButton() {
return (
<Link className="btn btn-secondary btn-block" to="/create_community">
- {i18n.t('create_a_community')}
+ {i18n.t("create_a_community")}
</Link>
);
}
admins() {
return (
<ul class="mt-1 list-inline small mb-0">
- <li class="list-inline-item">{i18n.t('admins')}:</li>
+ <li class="list-inline-item">{i18n.t("admins")}:</li>
{this.state.siteRes.admins.map(av => (
<li class="list-inline-item">
<UserListing user={av.user} />
return (
<ul class="my-2 list-inline">
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_online', { count: this.state.siteRes.online })}
+ {i18n.t("number_online", { count: this.state.siteRes.online })}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_day,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('day')}`}
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("day")}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_day,
- })}{' '}
- / {i18n.t('day')}
+ })}{" "}
+ / {i18n.t("day")}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_week,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('week')}`}
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("week")}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_week,
- })}{' '}
- / {i18n.t('week')}
+ })}{" "}
+ / {i18n.t("week")}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_month,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('month')}`}
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("month")}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_month,
- })}{' '}
- / {i18n.t('month')}
+ })}{" "}
+ / {i18n.t("month")}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_half_year,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('number_of_months', {
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("number_of_months", {
count: 6,
})}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_half_year,
- })}{' '}
- / {i18n.t('number_of_months', { count: 6 })}
+ })}{" "}
+ / {i18n.t("number_of_months", { count: 6 })}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_subscribers', {
+ {i18n.t("number_of_subscribers", {
count: counts.users,
})}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_communities', {
+ {i18n.t("number_of_communities", {
count: counts.communities,
})}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_posts', {
+ {i18n.t("number_of_posts", {
count: counts.posts,
})}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_comments', {
+ {i18n.t("number_of_comments", {
count: counts.comments,
})}
</li>
<li className="list-inline-item">
<Link className="badge badge-secondary" to="/modlog">
- {i18n.t('modlog')}
+ {i18n.t("modlog")}
</Link>
</li>
</ul>
class="pointer"
role="button"
onClick={linkEvent(this, this.handleEditClick)}
- aria-label={i18n.t('edit')}
- data-tippy-content={i18n.t('edit')}
+ aria-label={i18n.t("edit")}
+ data-tippy-content={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
</span>
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
{this.state.posts.length > 0 && (
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
)}
</div>
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (msg.reconnect) {
WebSocketService.Instance.send(
this.state.siteRes.site_view = data.site_view;
this.state.showEditSite = false;
this.setState(this.state);
- toast(i18n.t('site_saved'));
+ toast(i18n.t("site_saved"));
} else if (op == UserOperation.GetPosts) {
let data = wsJsonToRes<GetPostsResponse>(msg).data;
this.state.posts = data.posts;
-import { Component, linkEvent } from 'inferno';
-import { Prompt } from 'inferno-router';
+import { Component, linkEvent } from "inferno";
+import { Prompt } from "inferno-router";
import {
mdToHtml,
randomStr,
pictrsDeleteToast,
setupTippy,
isBrowser,
-} from '../utils';
-import { UserService } from '../services';
-import autosize from 'autosize';
-import { i18n } from '../i18next';
-import { pictrsUri } from '../env';
-import { Icon, Spinner } from './icon';
+} from "../utils";
+import { UserService } from "../services";
+import autosize from "autosize";
+import { i18n } from "../i18next";
+import { pictrsUri } from "../env";
+import { Icon, Spinner } from "./icon";
interface MarkdownTextAreaProps {
initialContent: string;
if (textarea) {
autosize(textarea);
this.tribute.attach(textarea);
- textarea.addEventListener('tribute-replaced', () => {
+ textarea.addEventListener("tribute-replaced", () => {
this.state.content = textarea.value;
this.setState(this.state);
autosize.update(textarea);
if (nextProps.finished) {
this.state.previewMode = false;
this.state.loading = false;
- this.state.content = '';
+ this.state.content = "";
this.setState(this.state);
if (this.props.replyType) {
this.props.onReplyCancel();
<form id={this.formId} onSubmit={linkEvent(this, this.handleSubmit)}>
<Prompt
when={!this.props.hideNavigationWarnings && this.state.content}
- message={i18n.t('block_leaving')}
+ message={i18n.t("block_leaving")}
/>
<div class="form-group row">
<div className={`col-sm-12`}>
<textarea
id={this.id}
- className={`form-control ${this.state.previewMode && 'd-none'}`}
+ className={`form-control ${this.state.previewMode && "d-none"}`}
value={this.state.content}
onInput={linkEvent(this, this.handleContentChange)}
onPaste={linkEvent(this, this.handleImageUploadPaste)}
)}
</div>
<label class="sr-only" htmlFor={this.id}>
- {i18n.t('body')}
+ {i18n.t("body")}
</label>
</div>
<div class="row">
class="btn btn-sm btn-secondary mr-2"
onClick={linkEvent(this, this.handleReplyCancel)}
>
- {i18n.t('cancel')}
+ {i18n.t("cancel")}
</button>
)}
{this.state.content && (
<button
className={`btn btn-sm btn-secondary mr-2 ${
- this.state.previewMode && 'active'
+ this.state.previewMode && "active"
}`}
onClick={linkEvent(this, this.handlePreviewToggle)}
>
- {i18n.t('preview')}
+ {i18n.t("preview")}
</button>
)}
{/* A flex expander */}
<div class="flex-grow-1"></div>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('bold')}
- aria-label={i18n.t('bold')}
+ data-tippy-content={i18n.t("bold")}
+ aria-label={i18n.t("bold")}
onClick={linkEvent(this, this.handleInsertBold)}
>
<Icon icon="bold" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('italic')}
- aria-label={i18n.t('italic')}
+ data-tippy-content={i18n.t("italic")}
+ aria-label={i18n.t("italic")}
onClick={linkEvent(this, this.handleInsertItalic)}
>
<Icon icon="italic" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('link')}
- aria-label={i18n.t('link')}
+ data-tippy-content={i18n.t("link")}
+ aria-label={i18n.t("link")}
onClick={linkEvent(this, this.handleInsertLink)}
>
<Icon icon="link" classes="icon-inline" />
<form class="btn btn-sm text-muted font-weight-bold">
<label
htmlFor={`file-upload-${this.id}`}
- className={`mb-0 ${UserService.Instance.user && 'pointer'}`}
- data-tippy-content={i18n.t('upload_image')}
+ className={`mb-0 ${UserService.Instance.user && "pointer"}`}
+ data-tippy-content={i18n.t("upload_image")}
>
{this.state.imageLoading ? (
<Spinner />
</form>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('header')}
- aria-label={i18n.t('header')}
+ data-tippy-content={i18n.t("header")}
+ aria-label={i18n.t("header")}
onClick={linkEvent(this, this.handleInsertHeader)}
>
<Icon icon="header" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('strikethrough')}
- aria-label={i18n.t('strikethrough')}
+ data-tippy-content={i18n.t("strikethrough")}
+ aria-label={i18n.t("strikethrough")}
onClick={linkEvent(this, this.handleInsertStrikethrough)}
>
<Icon icon="strikethrough" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('quote')}
- aria-label={i18n.t('quote')}
+ data-tippy-content={i18n.t("quote")}
+ aria-label={i18n.t("quote")}
onClick={linkEvent(this, this.handleInsertQuote)}
>
<Icon icon="format_quote" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('list')}
- aria-label={i18n.t('list')}
+ data-tippy-content={i18n.t("list")}
+ aria-label={i18n.t("list")}
onClick={linkEvent(this, this.handleInsertList)}
>
<Icon icon="list" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('code')}
- aria-label={i18n.t('code')}
+ data-tippy-content={i18n.t("code")}
+ aria-label={i18n.t("code")}
onClick={linkEvent(this, this.handleInsertCode)}
>
<Icon icon="code" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('subscript')}
- aria-label={i18n.t('subscript')}
+ data-tippy-content={i18n.t("subscript")}
+ aria-label={i18n.t("subscript")}
onClick={linkEvent(this, this.handleInsertSubscript)}
>
<Icon icon="subscript" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('superscript')}
- aria-label={i18n.t('superscript')}
+ data-tippy-content={i18n.t("superscript")}
+ aria-label={i18n.t("superscript")}
onClick={linkEvent(this, this.handleInsertSuperscript)}
>
<Icon icon="superscript" classes="icon-inline" />
</button>
<button
class="btn btn-sm text-muted"
- data-tippy-content={i18n.t('spoiler')}
- aria-label={i18n.t('spoiler')}
+ data-tippy-content={i18n.t("spoiler")}
+ aria-label={i18n.t("spoiler")}
onClick={linkEvent(this, this.handleInsertSpoiler)}
>
<Icon icon="alert-triangle" classes="icon-inline" />
<a
href={markdownHelpUrl}
class="btn btn-sm text-muted font-weight-bold"
- title={i18n.t('formatting_help')}
+ title={i18n.t("formatting_help")}
rel="noopener"
>
<Icon icon="help-circle" classes="icon-inline" />
}
const formData = new FormData();
- formData.append('images[]', file);
+ formData.append("images[]", file);
i.state.imageLoading = true;
i.setState(i.state);
fetch(pictrsUri, {
- method: 'POST',
+ method: "POST",
body: formData,
})
.then(res => res.json())
.then(res => {
- console.log('pictrs upload:');
+ console.log("pictrs upload:");
console.log(res);
- if (res.msg == 'ok') {
+ if (res.msg == "ok") {
let hash = res.files[0].file;
let url = `${pictrsUri}/${hash}`;
let deleteToken = res.files[0].delete_token;
let textarea: any = document.getElementById(i.id);
autosize.update(textarea);
pictrsDeleteToast(
- i18n.t('click_to_delete_picture'),
- i18n.t('picture_deleted'),
+ i18n.t("click_to_delete_picture"),
+ i18n.t("picture_deleted"),
deleteUrl
);
} else {
i.state.imageLoading = false;
i.setState(i.state);
- toast(JSON.stringify(res), 'danger');
+ toast(JSON.stringify(res), "danger");
}
})
.catch(error => {
i.state.imageLoading = false;
i.setState(i.state);
- toast(error, 'danger');
+ toast(error, "danger");
});
}
handleInsertLink(i: MarkdownTextArea, event: any) {
event.preventDefault();
if (!i.state.content) {
- i.state.content = '';
+ i.state.content = "";
}
let textarea: any = document.getElementById(i.id);
let start: number = textarea.selectionStart;
textarea.focus();
setTimeout(() => (textarea.selectionEnd = end + 3), 10);
} else {
- i.state.content += '[]()';
+ i.state.content += "[]()";
textarea.focus();
setTimeout(() => (textarea.selectionEnd -= 1), 10);
}
}
simpleBeginningofLine(chars: string) {
- this.simpleSurroundBeforeAfter(`${chars} `, '', '');
+ this.simpleSurroundBeforeAfter(`${chars} `, "", "");
}
simpleSurroundBeforeAfter(
beforeChars: string,
afterChars: string,
- emptyChars = '___'
+ emptyChars = "___"
) {
if (!this.state.content) {
- this.state.content = '';
+ this.state.content = "";
}
let textarea: any = document.getElementById(this.id);
let start: number = textarea.selectionStart;
handleInsertBold(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleSurround('**');
+ i.simpleSurround("**");
}
handleInsertItalic(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleSurround('*');
+ i.simpleSurround("*");
}
handleInsertCode(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleSurround('`');
+ i.simpleSurround("`");
}
handleInsertStrikethrough(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleSurround('~~');
+ i.simpleSurround("~~");
}
handleInsertList(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleBeginningofLine('-');
+ i.simpleBeginningofLine("-");
}
handleInsertQuote(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleBeginningofLine('>');
+ i.simpleBeginningofLine(">");
}
handleInsertHeader(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleBeginningofLine('#');
+ i.simpleBeginningofLine("#");
}
handleInsertSubscript(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleSurround('~');
+ i.simpleSurround("~");
}
handleInsertSuperscript(i: MarkdownTextArea, event: any) {
event.preventDefault();
- i.simpleSurround('^');
+ i.simpleSurround("^");
}
simpleInsert(chars: string) {
handleInsertSpoiler(i: MarkdownTextArea, event: any) {
event.preventDefault();
- let beforeChars = `\n::: spoiler ${i18n.t('spoiler')}\n`;
- let afterChars = '\n:::\n';
+ let beforeChars = `\n::: spoiler ${i18n.t("spoiler")}\n`;
+ let afterChars = "\n:::\n";
i.simpleSurroundBeforeAfter(beforeChars, afterChars);
}
if (selectedText) {
let quotedText =
selectedText
- .split('\n')
+ .split("\n")
.map(t => `> ${t}`)
- .join('\n') + '\n\n';
+ .join("\n") + "\n\n";
if (this.state.content == null) {
- this.state.content = '';
+ this.state.content = "";
} else {
- this.state.content += '\n';
+ this.state.content += "\n";
}
this.state.content += quotedText;
this.setState(this.state);
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
+import { Subscription } from "rxjs";
import {
UserOperation,
GetModlog,
ModBanView,
ModAddCommunityView,
ModAddView,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
wsJsonToRes,
fetchLimit,
isBrowser,
wsUserOp,
wsClient,
-} from '../utils';
-import { MomentTime } from './moment-time';
-import { HtmlTags } from './html-tags';
-import moment from 'moment';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { Spinner } from './icon';
+} from "../utils";
+import { MomentTime } from "./moment-time";
+import { HtmlTags } from "./html-tags";
+import moment from "moment";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { Spinner } from "./icon";
enum ModlogEnum {
ModRemovePost,
case ModlogEnum.ModRemovePost: {
let mrpv = i.view as ModRemovePostView;
return [
- mrpv.mod_remove_post.removed ? 'Removed ' : 'Restored ',
+ mrpv.mod_remove_post.removed ? "Removed " : "Restored ",
<span>
Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link>
</span>,
case ModlogEnum.ModLockPost: {
let mlpv = i.view as ModLockPostView;
return [
- mlpv.mod_lock_post.locked ? 'Locked ' : 'Unlocked ',
+ mlpv.mod_lock_post.locked ? "Locked " : "Unlocked ",
<span>
Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link>
</span>,
case ModlogEnum.ModStickyPost: {
let mspv = i.view as ModStickyPostView;
return [
- mspv.mod_sticky_post.stickied ? 'Stickied ' : 'Unstickied ',
+ mspv.mod_sticky_post.stickied ? "Stickied " : "Unstickied ",
<span>
Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link>
</span>,
case ModlogEnum.ModRemoveComment: {
let mrc = i.view as ModRemoveCommentView;
return [
- mrc.mod_remove_comment.removed ? 'Removed ' : 'Restored ',
+ mrc.mod_remove_comment.removed ? "Removed " : "Restored ",
<span>
- Comment{' '}
+ Comment{" "}
<Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}>
{mrc.comment.content}
</Link>
</span>,
<span>
- {' '}
+ {" "}
by <UserListing user={mrc.commenter} />
</span>,
mrc.mod_remove_comment.reason &&
case ModlogEnum.ModRemoveCommunity: {
let mrco = i.view as ModRemoveCommunityView;
return [
- mrco.mod_remove_community.removed ? 'Removed ' : 'Restored ',
+ mrco.mod_remove_community.removed ? "Removed " : "Restored ",
<span>
Community <CommunityLink community={mrco.community} />
</span>,
let mbfc = i.view as ModBanFromCommunityView;
return [
<span>
- {mbfc.mod_ban_from_community.banned ? 'Banned ' : 'Unbanned '}{' '}
+ {mbfc.mod_ban_from_community.banned ? "Banned " : "Unbanned "}{" "}
</span>,
<span>
<UserListing user={mbfc.banned_user} />
let mac = i.view as ModAddCommunityView;
return [
<span>
- {mac.mod_add_community.removed ? 'Removed ' : 'Appointed '}{' '}
+ {mac.mod_add_community.removed ? "Removed " : "Appointed "}{" "}
</span>,
<span>
<UserListing user={mac.modded_user} />
case ModlogEnum.ModBan: {
let mb = i.view as ModBanView;
return [
- <span>{mb.mod_ban.banned ? 'Banned ' : 'Unbanned '} </span>,
+ <span>{mb.mod_ban.banned ? "Banned " : "Unbanned "} </span>,
<span>
<UserListing user={mb.banned_user} />
</span>,
case ModlogEnum.ModAdd: {
let ma = i.view as ModAddView;
return [
- <span>{ma.mod_add.removed ? 'Removed ' : 'Appointed '} </span>,
+ <span>{ma.mod_add.removed ? "Removed " : "Appointed "} </span>,
<span>
<UserListing user={ma.modded_user} />
</span>,
className="text-body"
to={`/c/${this.state.communityName}`}
>
- /c/{this.state.communityName}{' '}
+ /c/{this.state.communityName}{" "}
</Link>
)}
- <span>{i18n.t('modlog')}</span>
+ <span>{i18n.t("modlog")}</span>
</h5>
<div class="table-responsive">
<table id="modlog_table" class="table table-sm table-hover">
<thead class="pointer">
<tr>
- <th> {i18n.t('time')}</th>
- <th>{i18n.t('mod')}</th>
- <th>{i18n.t('action')}</th>
+ <th> {i18n.t("time")}</th>
+ <th>{i18n.t("mod")}</th>
+ <th>{i18n.t("action")}</th>
</tr>
</thead>
{this.combined()}
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
<button
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
</div>
);
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let communityId = pathSplit[3];
let promises: Promise<any>[] = [];
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (op == UserOperation.GetModlog) {
let data = wsJsonToRes<GetModlogResponse>(msg).data;
-import { Component } from 'inferno';
-import moment from 'moment';
-import { getMomentLanguage, capitalizeFirstLetter } from '../utils';
-import { i18n } from '../i18next';
-import { Icon } from './icon';
+import { Component } from "inferno";
+import moment from "moment";
+import { getMomentLanguage, capitalizeFirstLetter } from "../utils";
+import { i18n } from "../i18next";
+import { Icon } from "./icon";
interface MomentTimeProps {
data: {
return (
<span
data-tippy-content={`${capitalizeFirstLetter(
- i18n.t('modified')
+ i18n.t("modified")
)} ${this.format(this.props.data.updated)}`}
className="font-italics pointer unselectable"
>
}
format(input: string): string {
- return moment.utc(input).local().format('LLLL');
+ return moment.utc(input).local().format("LLLL");
}
}
-import { Component, linkEvent, createRef, RefObject } from 'inferno';
-import { Link } from 'inferno-router';
-import { Subscription } from 'rxjs';
-import { WebSocketService, UserService } from '../services';
+import { Component, linkEvent, createRef, RefObject } from "inferno";
+import { Link } from "inferno-router";
+import { Subscription } from "rxjs";
+import { WebSocketService, UserService } from "../services";
import {
UserOperation,
GetReplies,
CommentResponse,
PrivateMessageResponse,
PrivateMessageView,
-} from 'lemmy-js-client';
+} from "lemmy-js-client";
import {
wsJsonToRes,
showAvatars,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import { i18n } from '../i18next';
-import { PictrsImage } from './pictrs-image';
-import { Icon } from './icon';
+} from "../utils";
+import { i18n } from "../i18next";
+import { PictrsImage } from "./pictrs-image";
+import { Icon } from "./icon";
interface NavbarProps {
site_res: GetSiteResponse;
mentions: [],
messages: [],
expanded: false,
- searchParam: '',
+ searchParam: "",
toggleSearch: false,
};
subscription: any;
updateUrl() {
const searchParam = this.state.searchParam;
- this.setState({ searchParam: '' });
+ this.setState({ searchParam: "" });
this.setState({ toggleSearch: false });
- if (searchParam === '') {
+ if (searchParam === "") {
this.context.router.history.push(`/search/`);
} else {
const searchParamEncoded = encodeURIComponent(searchParam);
}
handleSearchBlur(i: Navbar, event: any) {
- if (!(event.relatedTarget && event.relatedTarget.name !== 'search-btn')) {
+ if (!(event.relatedTarget && event.relatedTarget.name !== "search-btn")) {
i.state.toggleSearch = false;
i.setState(i.state);
}
<Link
className="ml-auto p-1 navbar-toggler nav-link border-0"
to="/inbox"
- title={i18n.t('inbox')}
+ title={i18n.t("inbox")}
>
<Icon icon="bell" />
{this.state.unreadCount > 0 && (
<span
class="mx-1 badge badge-light"
aria-label={`${this.state.unreadCount} ${i18n.t(
- 'unread_messages'
+ "unread_messages"
)}`}
>
{this.state.unreadCount}
type="button"
aria-label="menu"
onClick={linkEvent(this, this.expandNavbar)}
- data-tippy-content={i18n.t('expand_here')}
+ data-tippy-content={i18n.t("expand_here")}
>
<Icon icon="menu" />
</button>
<div
- className={`${!this.state.expanded && 'collapse'} navbar-collapse`}
+ className={`${!this.state.expanded && "collapse"} navbar-collapse`}
>
<ul class="navbar-nav my-2 mr-auto">
<li class="nav-item">
<Link
className="nav-link"
to="/communities"
- title={i18n.t('communities')}
+ title={i18n.t("communities")}
>
- {i18n.t('communities')}
+ {i18n.t("communities")}
</Link>
</li>
<li class="nav-item">
<Link
className="nav-link"
to={{
- pathname: '/create_post',
+ pathname: "/create_post",
state: { prevPath: this.currentLocation },
}}
- title={i18n.t('create_post')}
+ title={i18n.t("create_post")}
>
- {i18n.t('create_post')}
+ {i18n.t("create_post")}
</Link>
</li>
<li class="nav-item">
<Link
className="nav-link"
to="/create_community"
- title={i18n.t('create_community')}
+ title={i18n.t("create_community")}
>
- {i18n.t('create_community')}
+ {i18n.t("create_community")}
</Link>
</li>
<li class="nav-item">
<a
className="nav-link"
- title={i18n.t('support_lemmy')}
+ title={i18n.t("support_lemmy")}
href={supportLemmyUrl}
>
<Icon icon="beer" classes="small" />
<Link
className="nav-link"
to={`/admin`}
- title={i18n.t('admin_settings')}
+ title={i18n.t("admin_settings")}
>
<Icon icon="settings" />
</Link>
<input
id="search-input"
class={`form-control mr-0 search-input ${
- this.state.toggleSearch ? 'show-input' : 'hide-input'
+ this.state.toggleSearch ? "show-input" : "hide-input"
}`}
onInput={linkEvent(this, this.handleSearchParam)}
value={this.state.searchParam}
ref={this.searchTextField}
type="text"
- placeholder={i18n.t('search')}
+ placeholder={i18n.t("search")}
onBlur={linkEvent(this, this.handleSearchBlur)}
></input>
<label class="sr-only" htmlFor="search-input">
- {i18n.t('search')}
+ {i18n.t("search")}
</label>
<button
name="search-btn"
onClick={linkEvent(this, this.handleSearchBtn)}
class="px-1 btn btn-link"
style="color: var(--gray)"
- aria-label={i18n.t('search')}
+ aria-label={i18n.t("search")}
>
<Icon icon="search" />
</button>
<Link
className="nav-link"
to="/inbox"
- title={i18n.t('inbox')}
+ title={i18n.t("inbox")}
>
<Icon icon="bell" />
{this.state.unreadCount > 0 && (
<span
class="ml-1 badge badge-light"
aria-label={`${this.state.unreadCount} ${i18n.t(
- 'unread_messages'
+ "unread_messages"
)}`}
>
{this.state.unreadCount}
<Link
className="nav-link"
to={`/u/${user.name}`}
- title={i18n.t('settings')}
+ title={i18n.t("settings")}
>
<span>
{user.avatar && showAvatars() && (
<Link
className="btn btn-success"
to="/login"
- title={i18n.t('login_sign_up')}
+ title={i18n.t("login_sign_up")}
>
- {i18n.t('login_sign_up')}
+ {i18n.t("login_sign_up")}
</Link>
</li>
</ul>
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- if (msg.error == 'not_logged_in') {
+ if (msg.error == "not_logged_in") {
UserService.Instance.logout();
location.reload();
}
}
fetchUnreads() {
- console.log('Fetching unreads...');
+ console.log("Fetching unreads...");
let repliesForm: GetReplies = {
sort: SortType.New,
unread_only: true,
auth: authField(),
};
- if (this.currentLocation !== '/inbox') {
+ if (this.currentLocation !== "/inbox") {
WebSocketService.Instance.send(wsClient.getReplies(repliesForm));
WebSocketService.Instance.send(
wsClient.getUserMentions(userMentionsForm)
requestNotificationPermission() {
if (UserService.Instance.user) {
- document.addEventListener('DOMContentLoaded', function () {
+ document.addEventListener("DOMContentLoaded", function () {
if (!Notification) {
- toast(i18n.t('notifications_error'), 'danger');
+ toast(i18n.t("notifications_error"), "danger");
return;
}
- if (Notification.permission !== 'granted')
+ if (Notification.permission !== "granted")
Notification.requestPermission();
});
}
-import { Component } from 'inferno';
-import { i18n } from '../i18next';
+import { Component } from "inferno";
+import { i18n } from "../i18next";
export class NoMatch extends Component<any, any> {
- private errCode = new URLSearchParams(this.props.location.search).get('err');
+ private errCode = new URLSearchParams(this.props.location.search).get("err");
constructor(props: any, context: any) {
super(props, context);
<h1>404</h1>
{this.errCode && (
<h3>
- {i18n.t('code')}: {i18n.t(this.errCode)}
+ {i18n.t("code")}: {i18n.t(this.errCode)}
</h3>
)}
</div>
-import { Component, linkEvent } from 'inferno';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Subscription } from "rxjs";
import {
UserOperation,
LoginResponse,
PasswordChange as PasswordChangeForm,
SiteView,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
import {
wsJsonToRes,
capitalizeFirstLetter,
wsSubscribe,
wsUserOp,
wsClient,
-} from '../utils';
-import { i18n } from '../i18next';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
+} from "../utils";
+import { i18n } from "../i18next";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
interface State {
passwordChangeForm: PasswordChangeForm;
}
get documentTitle(): string {
- return `${i18n.t('password_change')} - ${this.state.site_view.site.name}`;
+ return `${i18n.t("password_change")} - ${this.state.site_view.site.name}`;
}
render() {
/>
<div class="row">
<div class="col-12 col-lg-6 offset-lg-3 mb-4">
- <h5>{i18n.t('password_change')}</h5>
+ <h5>{i18n.t("password_change")}</h5>
{this.passwordChangeForm()}
</div>
</div>
<form onSubmit={linkEvent(this, this.handlePasswordChangeSubmit)}>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="new-password">
- {i18n.t('new_password')}
+ {i18n.t("new_password")}
</label>
<div class="col-sm-10">
<input
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="verify-password">
- {i18n.t('verify_password')}
+ {i18n.t("verify_password")}
</label>
<div class="col-sm-10">
<input
{this.state.loading ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
)}
</button>
</div>
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state.loading = false;
this.setState(this.state);
return;
this.state = this.emptyState;
this.setState(this.state);
UserService.Instance.login(data);
- this.props.history.push('/');
+ this.props.history.push("/");
}
}
}
-import { Component } from 'inferno';
+import { Component } from "inferno";
const iconThumbnailSize = 96;
const thumbnailSize = 256;
render() {
return (
<picture>
- <source srcSet={this.src('webp')} type="image/webp" />
- <source srcSet={this.src('jpg')} type="image/jpeg" />
+ <source srcSet={this.src("webp")} type="image/webp" />
+ <source srcSet={this.src("jpg")} type="image/jpeg" />
<img
- src={this.src('jpg')}
+ src={this.src("jpg")}
alt={this.alt()}
className={`
- ${!this.props.icon && !this.props.iconOverlay && 'img-fluid '}
+ ${!this.props.icon && !this.props.iconOverlay && "img-fluid "}
${
this.props.thumbnail && !this.props.icon
- ? 'thumbnail rounded '
- : 'img-expanded '
+ ? "thumbnail rounded "
+ : "img-expanded "
}
- ${this.props.thumbnail && this.props.nsfw && 'img-blur '}
- ${this.props.icon && 'rounded-circle img-icon mr-2 '}
- ${this.props.iconOverlay && 'ml-2 mb-0 rounded-circle avatar-overlay '}
- ${this.props.pushup && 'avatar-pushup '}
+ ${this.props.thumbnail && this.props.nsfw && "img-blur "}
+ ${this.props.icon && "rounded-circle img-icon mr-2 "}
+ ${this.props.iconOverlay && "ml-2 mb-0 rounded-circle avatar-overlay "}
+ ${this.props.pushup && "avatar-pushup "}
`}
/>
</picture>
// sample url:
// http://localhost:8535/pictrs/image/file.png?thumbnail=256&format=jpg
- let split = this.props.src.split('/pictrs/image/');
+ let split = this.props.src.split("/pictrs/image/");
// If theres not multiple, then its not a pictrs image
if (split.length == 1) {
let params = { format };
if (this.props.thumbnail) {
- params['thumbnail'] = thumbnailSize;
+ params["thumbnail"] = thumbnailSize;
} else if (this.props.icon) {
- params['thumbnail'] = iconThumbnailSize;
+ params["thumbnail"] = iconThumbnailSize;
} else {
- params['thumbnail'] = maxImageSize;
+ params["thumbnail"] = maxImageSize;
}
let paramsStr = `?${new URLSearchParams(params).toString()}`;
alt(): string {
if (this.props.icon) {
- return '';
+ return "";
}
- return this.props.alt || '';
+ return this.props.alt || "";
}
}
-import { Component, linkEvent } from 'inferno';
-import { Prompt } from 'inferno-router';
-import { PostListings } from './post-listings';
-import { MarkdownTextArea } from './markdown-textarea';
-import { Icon, Spinner } from './icon';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Prompt } from "inferno-router";
+import { PostListings } from "./post-listings";
+import { MarkdownTextArea } from "./markdown-textarea";
+import { Icon, Spinner } from "./icon";
+import { Subscription } from "rxjs";
import {
CreatePost,
EditPost,
Search,
SearchType,
SearchResponse,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
-import { PostFormParams } from '../interfaces';
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
+import { PostFormParams } from "../interfaces";
import {
wsJsonToRes,
getPageTitle,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import autosize from 'autosize';
+} from "../utils";
+import autosize from "autosize";
var Choices;
if (isBrowser()) {
- Choices = require('choices.js');
+ Choices = require("choices.js");
}
-import { i18n } from '../i18next';
-import { pictrsUri } from '../env';
+import { i18n } from "../i18next";
+import { pictrsUri } from "../env";
const MAX_POST_TITLE_LENGTH = 200;
componentDidMount() {
setupTippy();
this.setupCommunities();
- let textarea: any = document.getElementById('post-title');
+ let textarea: any = document.getElementById("post-title");
if (textarea) {
autosize(textarea);
}
this.state.postForm.url ||
this.state.postForm.body)
}
- message={i18n.t('block_leaving')}
+ message={i18n.t("block_leaving")}
/>
<form onSubmit={linkEvent(this, this.handlePostSubmit)}>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="post-url">
- {i18n.t('url')}
+ {i18n.t("url")}
</label>
<div class="col-sm-10">
<input
role="button"
onClick={linkEvent(this, this.copySuggestedTitle)}
>
- {i18n.t('copy_suggested_title', {
+ {i18n.t("copy_suggested_title", {
title: this.state.suggestedTitle,
})}
</div>
<label
htmlFor="file-upload"
className={`${
- UserService.Instance.user && 'pointer'
+ UserService.Instance.user && "pointer"
} d-inline-block float-right text-muted font-weight-bold`}
- data-tippy-content={i18n.t('upload_image')}
+ data-tippy-content={i18n.t("upload_image")}
>
<Icon icon="image" classes="icon-inline" />
</label>
class="mr-2 d-inline-block float-right text-muted small font-weight-bold"
rel="noopener"
>
- {i18n.t('archive_link')}
+ {i18n.t("archive_link")}
</a>
)}
{this.state.imageLoading && <Spinner />}
{this.state.crossPosts.length > 0 && (
<>
<div class="my-1 text-muted small font-weight-bold">
- {i18n.t('cross_posts')}
+ {i18n.t("cross_posts")}
</div>
<PostListings
showCommunity
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="post-title">
- {i18n.t('title')}
+ {i18n.t("title")}
</label>
<div class="col-sm-10">
<textarea
id="post-title"
onInput={linkEvent(this, this.handlePostNameChange)}
class={`form-control ${
- !validTitle(this.state.postForm.name) && 'is-invalid'
+ !validTitle(this.state.postForm.name) && "is-invalid"
}`}
required
rows={1}
/>
{!validTitle(this.state.postForm.name) && (
<div class="invalid-feedback">
- {i18n.t('invalid_post_title')}
+ {i18n.t("invalid_post_title")}
</div>
)}
{this.state.suggestedPosts.length > 0 && (
<>
<div class="my-1 text-muted small font-weight-bold">
- {i18n.t('related_posts')}
+ {i18n.t("related_posts")}
</div>
<PostListings
posts={this.state.suggestedPosts}
</div>
<div class="form-group row">
- <label class="col-sm-2 col-form-label">{i18n.t('body')}</label>
+ <label class="col-sm-2 col-form-label">{i18n.t("body")}</label>
<div class="col-sm-10">
<MarkdownTextArea
initialContent={this.state.postForm.body}
{!this.props.post_view && (
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="post-community">
- {i18n.t('community')}
+ {i18n.t("community")}
</label>
<div class="col-sm-10">
<select
value={this.state.postForm.community_id}
onInput={linkEvent(this, this.handlePostCommunityChange)}
>
- <option>{i18n.t('select_a_community')}</option>
+ <option>{i18n.t("select_a_community")}</option>
{this.props.communities.map(cv => (
<option value={cv.community.id}>
{cv.community.local
onChange={linkEvent(this, this.handlePostNsfwChange)}
/>
<label class="form-check-label" htmlFor="post-nsfw">
- {i18n.t('nsfw')}
+ {i18n.t("nsfw")}
</label>
</div>
</div>
{this.state.loading ? (
<Spinner />
) : this.props.post_view ? (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
) : (
- capitalizeFirstLetter(i18n.t('create'))
+ capitalizeFirstLetter(i18n.t("create"))
)}
</button>
{this.props.post_view && (
class="btn btn-secondary"
onClick={linkEvent(this, this.handleCancel)}
>
- {i18n.t('cancel')}
+ {i18n.t("cancel")}
</button>
)}
</div>
event.preventDefault();
// Coerce empty url string to undefined
- if (i.state.postForm.url !== undefined && i.state.postForm.url === '') {
+ if (i.state.postForm.url !== undefined && i.state.postForm.url === "") {
i.state.postForm.url = undefined;
}
);
i.state.suggestedTitle = undefined;
setTimeout(() => {
- let textarea: any = document.getElementById('post-title');
+ let textarea: any = document.getElementById("post-title");
autosize.update(textarea);
}, 10);
i.setState(i.state);
auth: authField(false),
};
- if (this.state.postForm.name !== '') {
+ if (this.state.postForm.name !== "") {
WebSocketService.Instance.send(wsClient.search(form));
} else {
this.state.suggestedPosts = [];
}
const formData = new FormData();
- formData.append('images[]', file);
+ formData.append("images[]", file);
i.state.imageLoading = true;
i.setState(i.state);
fetch(pictrsUri, {
- method: 'POST',
+ method: "POST",
body: formData,
})
.then(res => res.json())
.then(res => {
- console.log('pictrs upload:');
+ console.log("pictrs upload:");
console.log(res);
- if (res.msg == 'ok') {
+ if (res.msg == "ok") {
let hash = res.files[0].file;
let url = `${pictrsUri}/${hash}`;
let deleteToken = res.files[0].delete_token;
i.state.imageLoading = false;
i.setState(i.state);
pictrsDeleteToast(
- i18n.t('click_to_delete_picture'),
- i18n.t('picture_deleted'),
+ i18n.t("click_to_delete_picture"),
+ i18n.t("picture_deleted"),
deleteUrl
);
} else {
i.state.imageLoading = false;
i.setState(i.state);
- toast(JSON.stringify(res), 'danger');
+ toast(JSON.stringify(res), "danger");
}
})
.catch(error => {
i.state.imageLoading = false;
i.setState(i.state);
- toast(error, 'danger');
+ toast(error, "danger");
});
}
setupCommunities() {
// Set up select searching
if (isBrowser()) {
- let selectId: any = document.getElementById('post-community');
+ let selectId: any = document.getElementById("post-community");
if (selectId) {
this.choices = new Choices(selectId, {
shouldSort: false,
classNames: {
- containerOuter: 'choices',
- containerInner: 'choices__inner bg-light border-0',
- input: 'form-control',
- inputCloned: 'choices__input--cloned',
- list: 'choices__list',
- listItems: 'choices__list--multiple',
- listSingle: 'choices__list--single',
- listDropdown: 'choices__list--dropdown',
- item: 'choices__item bg-light',
- itemSelectable: 'choices__item--selectable',
- itemDisabled: 'choices__item--disabled',
- itemChoice: 'choices__item--choice',
- placeholder: 'choices__placeholder',
- group: 'choices__group',
- groupHeading: 'choices__heading',
- button: 'choices__button',
- activeState: 'is-active',
- focusState: 'is-focused',
- openState: 'is-open',
- disabledState: 'is-disabled',
- highlightedState: 'text-info',
- selectedState: 'text-info',
- flippedState: 'is-flipped',
- loadingState: 'is-loading',
- noResults: 'has-no-results',
- noChoices: 'has-no-choices',
+ containerOuter: "choices",
+ containerInner: "choices__inner bg-light border-0",
+ input: "form-control",
+ inputCloned: "choices__input--cloned",
+ list: "choices__list",
+ listItems: "choices__list--multiple",
+ listSingle: "choices__list--single",
+ listDropdown: "choices__list--dropdown",
+ item: "choices__item bg-light",
+ itemSelectable: "choices__item--selectable",
+ itemDisabled: "choices__item--disabled",
+ itemChoice: "choices__item--choice",
+ placeholder: "choices__placeholder",
+ group: "choices__group",
+ groupHeading: "choices__heading",
+ button: "choices__button",
+ activeState: "is-active",
+ focusState: "is-focused",
+ openState: "is-open",
+ disabledState: "is-disabled",
+ highlightedState: "text-info",
+ selectedState: "text-info",
+ flippedState: "is-flipped",
+ loadingState: "is-loading",
+ noResults: "has-no-results",
+ noChoices: "has-no-choices",
},
});
this.choices.passedElement.element.addEventListener(
- 'choice',
+ "choice",
(e: any) => {
this.state.postForm.community_id = Number(e.detail.choice.value);
this.setState(this.state);
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state.loading = false;
this.setState(this.state);
return;
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
-import { WebSocketService, UserService } from '../services';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
+import { WebSocketService, UserService } from "../services";
import {
PostView,
CreatePostLike,
TransferSite,
TransferCommunity,
CommunityModeratorView,
-} from 'lemmy-js-client';
-import { BanType } from '../interfaces';
-import { MomentTime } from './moment-time';
-import { PostForm } from './post-form';
-import { IFramelyCard } from './iframely-card';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { PictrsImage } from './pictrs-image';
-import { Icon } from './icon';
+} from "lemmy-js-client";
+import { BanType } from "../interfaces";
+import { MomentTime } from "./moment-time";
+import { PostForm } from "./post-form";
+import { IFramelyCard } from "./iframely-card";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { PictrsImage } from "./pictrs-image";
+import { Icon } from "./icon";
import {
md,
mdToHtml,
previewLines,
wsClient,
authField,
-} from '../utils';
-import { i18n } from '../i18next';
-import { externalHost } from '../env';
+} from "../utils";
+import { i18n } from "../i18next";
+import { externalHost } from "../env";
interface PostListingState {
showEdit: boolean;
getImageSrc(): string {
let post = this.props.post_view.post;
if (isImage(post.url)) {
- if (post.url.includes('pictrs')) {
+ if (post.url.includes("pictrs")) {
return post.url;
} else if (post.thumbnail_url) {
return post.thumbnail_url;
return (
<div
class="float-right text-body pointer d-inline-block position-relative mb-2"
- data-tippy-content={i18n.t('expand_here')}
+ data-tippy-content={i18n.t("expand_here")}
onClick={linkEvent(this, this.handleImageExpandClick)}
role="button"
- aria-label={i18n.t('expand_here')}
+ aria-label={i18n.t("expand_here")}
>
{this.imgThumb(this.getImageSrc())}
<Icon icon="image" classes="mini-overlay" />
<Link
className="text-body"
to={`/post/${post.id}`}
- title={i18n.t('comments')}
+ title={i18n.t("comments")}
>
<div class="thumbnail rounded bg-light d-flex justify-content-center">
<Icon icon="message-square" classes="d-flex align-items-center" />
<UserListing user={post_view.creator} />
{this.isMod && (
- <span className="mx-1 badge badge-light">{i18n.t('mod')}</span>
+ <span className="mx-1 badge badge-light">{i18n.t("mod")}</span>
)}
{this.isAdmin && (
- <span className="mx-1 badge badge-light">{i18n.t('admin')}</span>
+ <span className="mx-1 badge badge-light">{i18n.t("admin")}</span>
)}
{(post_view.creator_banned_from_community ||
post_view.creator.banned) && (
- <span className="mx-1 badge badge-danger">{i18n.t('banned')}</span>
+ <span className="mx-1 badge badge-danger">{i18n.t("banned")}</span>
)}
{this.props.showCommunity && (
<span>
- <span class="mx-1"> {i18n.t('to')} </span>
+ <span class="mx-1"> {i18n.t("to")} </span>
<CommunityLink community={post_view.community} />
</span>
)}
previewLines(post_view.post.body)
)}
data-tippy-allowHtml={true}
- aria-label={i18n.t('upvote')}
+ aria-label={i18n.t("upvote")}
to={`/post/${post_view.post.id}`}
>
<Icon icon="book-open" classes="icon-inline mr-1" />
<div className={`vote-bar col-1 pr-0 small text-center`}>
<button
className={`btn-animate btn btn-link p-0 ${
- this.state.my_vote == 1 ? 'text-info' : 'text-muted'
+ this.state.my_vote == 1 ? "text-info" : "text-muted"
}`}
onClick={linkEvent(this, this.handlePostLike)}
- data-tippy-content={i18n.t('upvote')}
- aria-label={i18n.t('upvote')}
+ data-tippy-content={i18n.t("upvote")}
+ aria-label={i18n.t("upvote")}
>
<Icon icon="arrow-up1" classes="upvote" />
</button>
{this.props.enableDownvotes && (
<button
className={`btn-animate btn btn-link p-0 ${
- this.state.my_vote == -1 ? 'text-danger' : 'text-muted'
+ this.state.my_vote == -1 ? "text-danger" : "text-muted"
}`}
onClick={linkEvent(this, this.handlePostDisLike)}
- data-tippy-content={i18n.t('downvote')}
- aria-label={i18n.t('downvote')}
+ data-tippy-content={i18n.t("downvote")}
+ aria-label={i18n.t("downvote")}
>
<Icon icon="arrow-down1" classes="downvote" />
</button>
<h5>
{this.props.showBody && post.url ? (
<a
- className={!post.stickied ? 'text-body' : 'text-primary'}
+ className={!post.stickied ? "text-body" : "text-primary"}
href={post.url}
title={post.url}
rel="noopener"
</a>
) : (
<Link
- className={!post.stickied ? 'text-body' : 'text-primary'}
+ className={!post.stickied ? "text-body" : "text-primary"}
to={`/post/${post.id}`}
- title={i18n.t('comments')}
+ title={i18n.t("comments")}
>
{post.name}
</Link>
(!this.state.imageExpanded ? (
<span
class="text-monospace unselectable pointer ml-2 text-muted small"
- data-tippy-content={i18n.t('expand_here')}
+ data-tippy-content={i18n.t("expand_here")}
onClick={linkEvent(this, this.handleImageExpandClick)}
>
<Icon icon="plus-square" classes="icon-inline" />
))}
{post.removed && (
<small className="ml-2 text-muted font-italic">
- {i18n.t('removed')}
+ {i18n.t("removed")}
</small>
)}
{post.deleted && (
<small
className="unselectable pointer ml-2 text-muted font-italic"
- data-tippy-content={i18n.t('deleted')}
+ data-tippy-content={i18n.t("deleted")}
>
<Icon icon="trash" classes="icon-inline text-danger" />
</small>
{post.locked && (
<small
className="unselectable pointer ml-2 text-muted font-italic"
- data-tippy-content={i18n.t('locked')}
+ data-tippy-content={i18n.t("locked")}
>
<Icon icon="lock" classes="icon-inline text-danger" />
</small>
{post.stickied && (
<small
className="unselectable pointer ml-2 text-muted font-italic"
- data-tippy-content={i18n.t('stickied')}
+ data-tippy-content={i18n.t("stickied")}
>
<Icon icon="pin" classes="icon-inline text-primary" />
</small>
)}
{post.nsfw && (
<small className="ml-2 text-muted font-italic">
- {i18n.t('nsfw')}
+ {i18n.t("nsfw")}
</small>
)}
</h5>
<button class="btn btn-link text-muted p-0">
<Link
className="text-muted small"
- title={i18n.t('number_of_comments', {
+ title={i18n.t("number_of_comments", {
count: post_view.counts.comments,
})}
to={`/post/${post_view.post.id}`}
>
<Icon icon="message-square" classes="icon-inline mr-1" />
- {i18n.t('number_of_comments', {
+ {i18n.t("number_of_comments", {
count: post_view.counts.comments,
})}
</Link>
<button
class="btn text-muted py-0 pr-0"
data-tippy-content={this.pointsTippy}
- aria-label={i18n.t('downvote')}
+ aria-label={i18n.t("downvote")}
>
<small>
<Icon icon="arrow-down1" classes="icon-inline mr-1" />
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleSavePostClick)}
data-tippy-content={
- post_view.saved ? i18n.t('unsave') : i18n.t('save')
+ post_view.saved ? i18n.t("unsave") : i18n.t("save")
}
- aria-label={post_view.saved ? i18n.t('unsave') : i18n.t('save')}
+ aria-label={post_view.saved ? i18n.t("unsave") : i18n.t("save")}
>
<small>
<Icon
icon="star"
- classes={`icon-inline ${post_view.saved && 'text-warning'}`}
+ classes={`icon-inline ${post_view.saved && "text-warning"}`}
/>
</small>
</button>
<div>
<button
className={`btn-animate btn py-0 px-1 ${
- this.state.my_vote == 1 ? 'text-info' : 'text-muted'
+ this.state.my_vote == 1 ? "text-info" : "text-muted"
}`}
data-tippy-content={this.pointsTippy}
onClick={linkEvent(this, this.handlePostLike)}
- aria-label={i18n.t('upvote')}
+ aria-label={i18n.t("upvote")}
>
<Icon icon="arrow-up1" classes="icon-inline small mr-2" />
{this.state.upvotes}
{this.props.enableDownvotes && (
<button
className={`ml-2 btn-animate btn py-0 pl-1 ${
- this.state.my_vote == -1 ? 'text-danger' : 'text-muted'
+ this.state.my_vote == -1 ? "text-danger" : "text-muted"
}`}
onClick={linkEvent(this, this.handlePostDisLike)}
data-tippy-content={this.pointsTippy}
- aria-label={i18n.t('downvote')}
+ aria-label={i18n.t("downvote")}
>
<Icon icon="arrow-down1" classes="icon-inline small mr-2" />
{this.state.downvotes !== 0 && (
<button
class="btn btn-link btn-animate text-muted py-0 pl-1 pr-0"
onClick={linkEvent(this, this.handleSavePostClick)}
- aria-label={post_view.saved ? i18n.t('unsave') : i18n.t('save')}
+ aria-label={post_view.saved ? i18n.t("unsave") : i18n.t("save")}
data-tippy-content={
- post_view.saved ? i18n.t('unsave') : i18n.t('save')
+ post_view.saved ? i18n.t("unsave") : i18n.t("save")
}
>
<Icon
icon="star"
- classes={`icon-inline ${post_view.saved && 'text-warning'}`}
+ classes={`icon-inline ${post_view.saved && "text-warning"}`}
/>
</button>
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleShowMoreMobile)}
- aria-label={i18n.t('more')}
- data-tippy-content={i18n.t('more')}
+ aria-label={i18n.t("more")}
+ data-tippy-content={i18n.t("more")}
>
<Icon icon="more-vertical" classes="icon-inline" />
</button>
<ul class="list-inline mb-1 small text-muted">
<>
<li className="list-inline-item mr-2">
- {i18n.t('cross_posted_to')}
+ {i18n.t("cross_posted_to")}
</li>
{dupes.map(pv => (
<li className="list-inline-item mr-2">
class="btn btn-link btn-animate text-muted py-0 pl-0"
onClick={linkEvent(this, this.handleSavePostClick)}
data-tippy-content={
- post_view.saved ? i18n.t('unsave') : i18n.t('save')
+ post_view.saved ? i18n.t("unsave") : i18n.t("save")
}
aria-label={
- post_view.saved ? i18n.t('unsave') : i18n.t('save')
+ post_view.saved ? i18n.t("unsave") : i18n.t("save")
}
>
<Icon
icon="star"
- classes={`icon-inline ${post_view.saved && 'text-warning'}`}
+ classes={`icon-inline ${post_view.saved && "text-warning"}`}
/>
</button>
)}
<Link
className="btn btn-link btn-animate text-muted py-0"
to={`/create_post${this.crossPostParams}`}
- title={i18n.t('cross_post')}
+ title={i18n.t("cross_post")}
>
<Icon icon="copy" classes="icon-inline" />
</Link>
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleEditClick)}
- data-tippy-content={i18n.t('edit')}
- aria-label={i18n.t('edit')}
+ data-tippy-content={i18n.t("edit")}
+ aria-label={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
</button>
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
- !post_view.post.deleted ? i18n.t('delete') : i18n.t('restore')
+ !post_view.post.deleted ? i18n.t("delete") : i18n.t("restore")
}
aria-label={
- !post_view.post.deleted ? i18n.t('delete') : i18n.t('restore')
+ !post_view.post.deleted ? i18n.t("delete") : i18n.t("restore")
}
>
<Icon
icon="trash"
classes={`icon-inline ${
- post_view.post.deleted && 'text-danger'
+ post_view.post.deleted && "text-danger"
}`}
/>
</button>
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleShowAdvanced)}
- data-tippy-content={i18n.t('more')}
- aria-label={i18n.t('more')}
+ data-tippy-content={i18n.t("more")}
+ aria-label={i18n.t("more")}
>
<Icon icon="more-vertical" classes="icon-inline" />
</button>
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleViewSource)}
- data-tippy-content={i18n.t('view_source')}
- aria-label={i18n.t('view_source')}
+ data-tippy-content={i18n.t("view_source")}
+ aria-label={i18n.t("view_source")}
>
<Icon
icon="file-text"
classes={`icon-inline ${
- this.state.viewSource && 'text-success'
+ this.state.viewSource && "text-success"
}`}
/>
</button>
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModLock)}
data-tippy-content={
- post_view.post.locked ? i18n.t('unlock') : i18n.t('lock')
+ post_view.post.locked ? i18n.t("unlock") : i18n.t("lock")
}
aria-label={
- post_view.post.locked ? i18n.t('unlock') : i18n.t('lock')
+ post_view.post.locked ? i18n.t("unlock") : i18n.t("lock")
}
>
<Icon
icon="lock"
classes={`icon-inline ${
- post_view.post.locked && 'text-danger'
+ post_view.post.locked && "text-danger"
}`}
/>
</button>
onClick={linkEvent(this, this.handleModSticky)}
data-tippy-content={
post_view.post.stickied
- ? i18n.t('unsticky')
- : i18n.t('sticky')
+ ? i18n.t("unsticky")
+ : i18n.t("sticky")
}
aria-label={
post_view.post.stickied
- ? i18n.t('unsticky')
- : i18n.t('sticky')
+ ? i18n.t("unsticky")
+ : i18n.t("sticky")
}
>
<Icon
icon="pin"
classes={`icon-inline ${
- post_view.post.stickied && 'text-success'
+ post_view.post.stickied && "text-success"
}`}
/>
</button>
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModRemoveShow)}
- aria-label={i18n.t('remove')}
+ aria-label={i18n.t("remove")}
>
- {i18n.t('remove')}
+ {i18n.t("remove")}
</button>
) : (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModRemoveSubmit)}
- aria-label={i18n.t('restore')}
+ aria-label={i18n.t("restore")}
>
- {i18n.t('restore')}
+ {i18n.t("restore")}
</button>
))}
{this.canMod && (
this,
this.handleModBanFromCommunityShow
)}
- aria-label={i18n.t('ban')}
+ aria-label={i18n.t("ban")}
>
- {i18n.t('ban')}
+ {i18n.t("ban")}
</button>
) : (
<button
this,
this.handleModBanFromCommunitySubmit
)}
- aria-label={i18n.t('unban')}
+ aria-label={i18n.t("unban")}
>
- {i18n.t('unban')}
+ {i18n.t("unban")}
</button>
))}
{!post_view.creator_banned_from_community &&
onClick={linkEvent(this, this.handleAddModToCommunity)}
aria-label={
this.isMod
- ? i18n.t('remove_as_mod')
- : i18n.t('appoint_as_mod')
+ ? i18n.t("remove_as_mod")
+ : i18n.t("appoint_as_mod")
}
>
{this.isMod
- ? i18n.t('remove_as_mod')
- : i18n.t('appoint_as_mod')}
+ ? i18n.t("remove_as_mod")
+ : i18n.t("appoint_as_mod")}
</button>
)}
</>
this,
this.handleShowConfirmTransferCommunity
)}
- aria-label={i18n.t('transfer_community')}
+ aria-label={i18n.t("transfer_community")}
>
- {i18n.t('transfer_community')}
+ {i18n.t("transfer_community")}
</button>
) : (
<>
<button
class="d-inline-block mr-1 btn btn-link btn-animate text-muted py-0"
- aria-label={i18n.t('are_you_sure')}
+ aria-label={i18n.t("are_you_sure")}
>
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</button>
<button
class="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1"
- aria-label={i18n.t('yes')}
+ aria-label={i18n.t("yes")}
onClick={linkEvent(this, this.handleTransferCommunity)}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</button>
<button
class="btn btn-link btn-animate text-muted py-0 d-inline-block"
this,
this.handleCancelShowConfirmTransferCommunity
)}
- aria-label={i18n.t('no')}
+ aria-label={i18n.t("no")}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</button>
</>
))}
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModBanShow)}
- aria-label={i18n.t('ban_from_site')}
+ aria-label={i18n.t("ban_from_site")}
>
- {i18n.t('ban_from_site')}
+ {i18n.t("ban_from_site")}
</button>
) : (
<button
class="btn btn-link btn-animate text-muted py-0"
onClick={linkEvent(this, this.handleModBanSubmit)}
- aria-label={i18n.t('unban_from_site')}
+ aria-label={i18n.t("unban_from_site")}
>
- {i18n.t('unban_from_site')}
+ {i18n.t("unban_from_site")}
</button>
))}
{!post_view.creator.banned && post_view.creator.local && (
onClick={linkEvent(this, this.handleAddAdmin)}
aria-label={
this.isAdmin
- ? i18n.t('remove_as_admin')
- : i18n.t('appoint_as_admin')
+ ? i18n.t("remove_as_admin")
+ : i18n.t("appoint_as_admin")
}
>
{this.isAdmin
- ? i18n.t('remove_as_admin')
- : i18n.t('appoint_as_admin')}
+ ? i18n.t("remove_as_admin")
+ : i18n.t("appoint_as_admin")}
</button>
)}
</>
this,
this.handleShowConfirmTransferSite
)}
- aria-label={i18n.t('transfer_site')}
+ aria-label={i18n.t("transfer_site")}
>
- {i18n.t('transfer_site')}
+ {i18n.t("transfer_site")}
</button>
) : (
<>
<button
class="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1"
- aria-label={i18n.t('are_you_sure')}
+ aria-label={i18n.t("are_you_sure")}
>
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</button>
<button
class="btn btn-link btn-animate text-muted py-0 d-inline-block mr-1"
onClick={linkEvent(this, this.handleTransferSite)}
- aria-label={i18n.t('yes')}
+ aria-label={i18n.t("yes")}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</button>
<button
class="btn btn-link btn-animate text-muted py-0 d-inline-block"
this,
this.handleCancelShowConfirmTransferSite
)}
- aria-label={i18n.t('no')}
+ aria-label={i18n.t("no")}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</button>
</>
))}
onSubmit={linkEvent(this, this.handleModRemoveSubmit)}
>
<label class="sr-only" htmlFor="post-listing-remove-reason">
- {i18n.t('reason')}
+ {i18n.t("reason")}
</label>
<input
type="text"
id="post-listing-remove-reason"
class="form-control mr-2"
- placeholder={i18n.t('reason')}
+ placeholder={i18n.t("reason")}
value={this.state.removeReason}
onInput={linkEvent(this, this.handleModRemoveReasonChange)}
/>
<button
type="submit"
class="btn btn-secondary"
- aria-label={i18n.t('remove_post')}
+ aria-label={i18n.t("remove_post")}
>
- {i18n.t('remove_post')}
+ {i18n.t("remove_post")}
</button>
</form>
)}
<form onSubmit={linkEvent(this, this.handleModBanBothSubmit)}>
<div class="form-group row">
<label class="col-form-label" htmlFor="post-listing-ban-reason">
- {i18n.t('reason')}
+ {i18n.t("reason")}
</label>
<input
type="text"
id="post-listing-ban-reason"
class="form-control mr-2"
- placeholder={i18n.t('reason')}
+ placeholder={i18n.t("reason")}
value={this.state.banReason}
onInput={linkEvent(this, this.handleModBanReasonChange)}
/>
onChange={linkEvent(this, this.handleModRemoveDataChange)}
/>
<label class="form-check-label" htmlFor="mod-ban-remove-data">
- {i18n.t('remove_posts_comments')}
+ {i18n.t("remove_posts_comments")}
</label>
</div>
</div>
<button
type="submit"
class="btn btn-secondary"
- aria-label={i18n.t('ban')}
+ aria-label={i18n.t("ban")}
>
- {i18n.t('ban')} {post.creator.name}
+ {i18n.t("ban")} {post.creator.name}
</button>
</div>
</form>
let post = this.props.post_view.post;
return post.thumbnail_url || isImage(post.url) ? (
<div class="row">
- <div className={`${this.state.imageExpanded ? 'col-12' : 'col-8'}`}>
+ <div className={`${this.state.imageExpanded ? "col-12" : "col-8"}`}>
{this.postTitleLine()}
</div>
<div class="col-4">
)}
<div
class={`${
- this.state.imageExpanded ? 'col-12' : 'col-12 col-sm-9'
+ this.state.imageExpanded ? "col-12" : "col-12 col-sm-9"
}`}
>
<div class="row">
}
get pointsTippy(): string {
- let points = i18n.t('number_of_points', {
+ let points = i18n.t("number_of_points", {
count: this.state.score,
});
- let upvotes = i18n.t('number_of_upvotes', {
+ let upvotes = i18n.t("number_of_upvotes", {
count: this.state.upvotes,
});
- let downvotes = i18n.t('number_of_downvotes', {
+ let downvotes = i18n.t("number_of_downvotes", {
count: this.state.downvotes,
});
-import { Component } from 'inferno';
-import { Link } from 'inferno-router';
-import { PostView } from 'lemmy-js-client';
-import { PostListing } from './post-listing';
-import { i18n } from '../i18next';
-import { T } from 'inferno-i18next';
+import { Component } from "inferno";
+import { Link } from "inferno-router";
+import { PostView } from "lemmy-js-client";
+import { PostListing } from "./post-listing";
+import { i18n } from "../i18next";
+import { T } from "inferno-i18next";
interface PostListingsProps {
posts: PostView[];
))
) : (
<>
- <div>{i18n.t('no_posts')}</div>
+ <div>{i18n.t("no_posts")}</div>
{this.props.showCommunity !== undefined && (
<T i18nKey="subscribe_to_communities">
#<Link to="/communities">#</Link>
-import { Component, linkEvent } from 'inferno';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
+import { Subscription } from "rxjs";
import {
UserOperation,
PostView,
GetCommunityResponse,
ListCategoriesResponse,
Category,
-} from 'lemmy-js-client';
+} from "lemmy-js-client";
import {
CommentSortType,
CommentViewType,
InitialFetchRequest,
CommentNode as CommentNodeI,
-} from '../interfaces';
-import { WebSocketService, UserService } from '../services';
+} from "../interfaces";
+import { WebSocketService, UserService } from "../services";
import {
wsJsonToRes,
toast,
restoreScrollPosition,
buildCommentsTree,
insertCommentIntoTree,
-} from '../utils';
-import { PostListing } from './post-listing';
-import { Sidebar } from './sidebar';
-import { CommentForm } from './comment-form';
-import { CommentNodes } from './comment-nodes';
-import autosize from 'autosize';
-import { i18n } from '../i18next';
+} from "../utils";
+import { PostListing } from "./post-listing";
+import { Sidebar } from "./sidebar";
+import { CommentForm } from "./comment-form";
+import { CommentNodes } from "./comment-nodes";
+import autosize from "autosize";
+import { i18n } from "../i18next";
interface PostState {
postRes: GetPostResponse;
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let promises: Promise<any>[] = [];
let id = Number(pathSplit[2]);
WebSocketService.Instance.send(
wsClient.postJoin({ post_id: this.state.postId })
);
- autosize(document.querySelectorAll('textarea'));
+ autosize(document.querySelectorAll("textarea"));
}
componentDidUpdate(_lastProps: any, lastState: PostState) {
scrollCommentIntoView() {
var elmnt = document.getElementById(`comment-${this.state.commentId}`);
elmnt.scrollIntoView();
- elmnt.classList.add('mark');
+ elmnt.classList.add("mark");
this.state.scrolled = true;
this.markScrolledAsRead(this.state.commentId);
}
<div class="btn-group btn-group-toggle flex-wrap mr-3 mb-2">
<label
className={`btn btn-outline-secondary pointer ${
- this.state.commentSort === CommentSortType.Hot && 'active'
+ this.state.commentSort === CommentSortType.Hot && "active"
}`}
>
- {i18n.t('hot')}
+ {i18n.t("hot")}
<input
type="radio"
value={CommentSortType.Hot}
</label>
<label
className={`btn btn-outline-secondary pointer ${
- this.state.commentSort === CommentSortType.Top && 'active'
+ this.state.commentSort === CommentSortType.Top && "active"
}`}
>
- {i18n.t('top')}
+ {i18n.t("top")}
<input
type="radio"
value={CommentSortType.Top}
</label>
<label
className={`btn btn-outline-secondary pointer ${
- this.state.commentSort === CommentSortType.New && 'active'
+ this.state.commentSort === CommentSortType.New && "active"
}`}
>
- {i18n.t('new')}
+ {i18n.t("new")}
<input
type="radio"
value={CommentSortType.New}
</label>
<label
className={`btn btn-outline-secondary pointer ${
- this.state.commentSort === CommentSortType.Old && 'active'
+ this.state.commentSort === CommentSortType.Old && "active"
}`}
>
- {i18n.t('old')}
+ {i18n.t("old")}
<input
type="radio"
value={CommentSortType.Old}
<div class="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary pointer ${
- this.state.commentViewType === CommentViewType.Chat && 'active'
+ this.state.commentViewType === CommentViewType.Chat && "active"
}`}
>
- {i18n.t('chat')}
+ {i18n.t("chat")}
<input
type="radio"
value={CommentViewType.Chat}
let op = wsUserOp(msg);
console.log(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (msg.reconnect) {
let postId = Number(this.props.match.params.id);
-import { Component, linkEvent } from 'inferno';
-import { Prompt } from 'inferno-router';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Prompt } from "inferno-router";
+import { Subscription } from "rxjs";
import {
CreatePrivateMessage,
EditPrivateMessage,
PrivateMessageResponse,
UserSafe,
UserOperation,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
capitalizeFirstLetter,
wsJsonToRes,
wsUserOp,
wsClient,
authField,
-} from '../utils';
-import { UserListing } from './user-listing';
-import { MarkdownTextArea } from './markdown-textarea';
-import { Icon, Spinner } from './icon';
-import { i18n } from '../i18next';
-import { T } from 'inferno-i18next';
+} from "../utils";
+import { UserListing } from "./user-listing";
+import { MarkdownTextArea } from "./markdown-textarea";
+import { Icon, Spinner } from "./icon";
+import { i18n } from "../i18next";
+import { T } from "inferno-i18next";
interface PrivateMessageFormProps {
recipient: UserSafe;
<div>
<Prompt
when={!this.state.loading && this.state.privateMessageForm.content}
- message={i18n.t('block_leaving')}
+ message={i18n.t("block_leaving")}
/>
<form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
{!this.props.privateMessage && (
<div class="form-group row">
<label class="col-sm-2 col-form-label">
- {capitalizeFirstLetter(i18n.t('to'))}
+ {capitalizeFirstLetter(i18n.t("to"))}
</label>
<div class="col-sm-10 form-control-plaintext">
)}
<div class="form-group row">
<label class="col-sm-2 col-form-label">
- {i18n.t('message')}
+ {i18n.t("message")}
<span
onClick={linkEvent(this, this.handleShowDisclaimer)}
role="button"
class="ml-2 pointer text-danger"
- data-tippy-content={i18n.t('disclaimer')}
- aria-label={i18n.t('disclaimer')}
+ data-tippy-content={i18n.t("disclaimer")}
+ aria-label={i18n.t("disclaimer")}
>
<Icon icon="alert-triangle" classes="icon-inline" />
</span>
{this.state.loading ? (
<Spinner />
) : this.props.privateMessage ? (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
) : (
- capitalizeFirstLetter(i18n.t('send_message'))
+ capitalizeFirstLetter(i18n.t("send_message"))
)}
</button>
{this.props.privateMessage && (
class="btn btn-secondary"
onClick={linkEvent(this, this.handleCancel)}
>
- {i18n.t('cancel')}
+ {i18n.t("cancel")}
</button>
)}
<ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state.loading = false;
this.setState(this.state);
return;
-import { Component, linkEvent } from 'inferno';
+import { Component, linkEvent } from "inferno";
import {
PrivateMessageView,
DeletePrivateMessage,
MarkPrivateMessageAsRead,
UserSafe,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
-import { authField, mdToHtml, toast, wsClient } from '../utils';
-import { MomentTime } from './moment-time';
-import { PrivateMessageForm } from './private-message-form';
-import { UserListing } from './user-listing';
-import { Icon } from './icon';
-import { i18n } from '../i18next';
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
+import { authField, mdToHtml, toast, wsClient } from "../utils";
+import { MomentTime } from "./moment-time";
+import { PrivateMessageForm } from "./private-message-form";
+import { UserListing } from "./user-listing";
+import { Icon } from "./icon";
+import { i18n } from "../i18next";
interface PrivateMessageState {
showReply: boolean;
<ul class="list-inline mb-0 text-muted small">
{/* TODO refactor this */}
<li className="list-inline-item">
- {this.mine ? i18n.t('to') : i18n.t('from')}
+ {this.mine ? i18n.t("to") : i18n.t("from")}
</li>
<li className="list-inline-item">
<UserListing user={userOther} />
onClick={linkEvent(this, this.handleMarkRead)}
data-tippy-content={
message_view.private_message.read
- ? i18n.t('mark_as_unread')
- : i18n.t('mark_as_read')
+ ? i18n.t("mark_as_unread")
+ : i18n.t("mark_as_read")
}
aria-label={
message_view.private_message.read
- ? i18n.t('mark_as_unread')
- : i18n.t('mark_as_read')
+ ? i18n.t("mark_as_unread")
+ : i18n.t("mark_as_read")
}
>
<Icon
icon="check"
classes={`icon-inline ${
- message_view.private_message.read && 'text-success'
+ message_view.private_message.read && "text-success"
}`}
/>
</button>
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleReplyClick)}
- data-tippy-content={i18n.t('reply')}
- aria-label={i18n.t('reply')}
+ data-tippy-content={i18n.t("reply")}
+ aria-label={i18n.t("reply")}
>
<Icon icon="reply1" classes="icon-inline" />
</button>
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleEditClick)}
- data-tippy-content={i18n.t('edit')}
- aria-label={i18n.t('edit')}
+ data-tippy-content={i18n.t("edit")}
+ aria-label={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
</button>
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
!message_view.private_message.deleted
- ? i18n.t('delete')
- : i18n.t('restore')
+ ? i18n.t("delete")
+ : i18n.t("restore")
}
aria-label={
!message_view.private_message.deleted
- ? i18n.t('delete')
- : i18n.t('restore')
+ ? i18n.t("delete")
+ : i18n.t("restore")
}
>
<Icon
icon="trash"
classes={`icon-inline ${
message_view.private_message.deleted &&
- 'text-danger'
+ "text-danger"
}`}
/>
</button>
<button
class="btn btn-link btn-animate text-muted"
onClick={linkEvent(this, this.handleViewSource)}
- data-tippy-content={i18n.t('view_source')}
- aria-label={i18n.t('view_source')}
+ data-tippy-content={i18n.t("view_source")}
+ aria-label={i18n.t("view_source")}
>
<Icon
icon="file-text"
classes={`icon-inline ${
- this.state.viewSource && 'text-success'
+ this.state.viewSource && "text-success"
}`}
/>
</button>
get messageUnlessRemoved(): string {
let message = this.props.private_message_view.private_message;
- return message.deleted ? `*${i18n.t('deleted')}*` : message.content;
+ return message.deleted ? `*${i18n.t("deleted")}*` : message.content;
}
handleReplyClick(i: PrivateMessage) {
) {
this.state.showReply = false;
this.setState(this.state);
- toast(i18n.t('message_sent'));
+ toast(i18n.t("message_sent"));
}
}
}
-import { Component, linkEvent } from 'inferno';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Subscription } from "rxjs";
import {
UserOperation,
PostView,
PostResponse,
CommentResponse,
Site,
-} from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+} from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
wsJsonToRes,
fetchLimit,
setOptionalAuth,
saveScrollPosition,
restoreScrollPosition,
-} from '../utils';
-import { PostListing } from './post-listing';
-import { HtmlTags } from './html-tags';
-import { Spinner } from './icon';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { SortSelect } from './sort-select';
-import { CommentNodes } from './comment-nodes';
-import { i18n } from '../i18next';
-import { InitialFetchRequest } from 'shared/interfaces';
+} from "../utils";
+import { PostListing } from "./post-listing";
+import { HtmlTags } from "./html-tags";
+import { Spinner } from "./icon";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { SortSelect } from "./sort-select";
+import { CommentNodes } from "./comment-nodes";
+import { i18n } from "../i18next";
+import { InitialFetchRequest } from "shared/interfaces";
interface SearchProps {
q: string;
};
static getSearchQueryFromProps(q: string): string {
- return decodeURIComponent(q) || '';
+ return decodeURIComponent(q) || "";
}
static getSearchTypeFromProps(type_: string): SearchType {
this.subscription = wsSubscribe(this.parseMessage);
// Only fetch the data if coming from another route
- if (this.state.q != '') {
+ if (this.state.q != "") {
if (this.isoData.path == this.context.router.route.match.url) {
this.state.searchResponse = this.isoData.routeData[0];
this.state.loading = false;
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let promises: Promise<any>[] = [];
let form: SearchForm = {
};
setOptionalAuth(form, req.auth);
- if (form.q != '') {
+ if (form.q != "") {
promises.push(req.client.search(form));
}
get documentTitle(): string {
if (this.state.q) {
- return `${i18n.t('search')} - ${this.state.q} - ${this.state.site.name}`;
+ return `${i18n.t("search")} - ${this.state.q} - ${this.state.site.name}`;
} else {
- return `${i18n.t('search')} - ${this.state.site.name}`;
+ return `${i18n.t("search")} - ${this.state.site.name}`;
}
}
title={this.documentTitle}
path={this.context.router.route.match.url}
/>
- <h5>{i18n.t('search')}</h5>
+ <h5>{i18n.t("search")}</h5>
{this.selects()}
{this.searchForm()}
{this.state.type_ == SearchType.All && this.all()}
{this.state.type_ == SearchType.Posts && this.posts()}
{this.state.type_ == SearchType.Communities && this.communities()}
{this.state.type_ == SearchType.Users && this.users()}
- {this.resultsCount() == 0 && <span>{i18n.t('no_results')}</span>}
+ {this.resultsCount() == 0 && <span>{i18n.t("no_results")}</span>}
{this.paginator()}
</div>
);
type="text"
class="form-control mr-2 mb-2"
value={this.state.searchText}
- placeholder={`${i18n.t('search')}...`}
- aria-label={i18n.t('search')}
+ placeholder={`${i18n.t("search")}...`}
+ aria-label={i18n.t("search")}
onInput={linkEvent(this, this.handleQChange)}
required
minLength={3}
/>
<button type="submit" class="btn btn-secondary mr-2 mb-2">
- {this.state.loading ? <Spinner /> : <span>{i18n.t('search')}</span>}
+ {this.state.loading ? <Spinner /> : <span>{i18n.t("search")}</span>}
</button>
</form>
);
value={this.state.type_}
onChange={linkEvent(this, this.handleTypeChange)}
class="custom-select w-auto mb-2"
- aria-label={i18n.t('type')}
+ aria-label={i18n.t("type")}
>
<option disabled aria-hidden="true">
- {i18n.t('type')}
+ {i18n.t("type")}
</option>
- <option value={SearchType.All}>{i18n.t('all')}</option>
- <option value={SearchType.Comments}>{i18n.t('comments')}</option>
- <option value={SearchType.Posts}>{i18n.t('posts')}</option>
+ <option value={SearchType.All}>{i18n.t("all")}</option>
+ <option value={SearchType.Comments}>{i18n.t("comments")}</option>
+ <option value={SearchType.Posts}>{i18n.t("posts")}</option>
<option value={SearchType.Communities}>
- {i18n.t('communities')}
+ {i18n.t("communities")}
</option>
- <option value={SearchType.Users}>{i18n.t('users')}</option>
+ <option value={SearchType.Users}>{i18n.t("users")}</option>
</select>
<span class="ml-2">
<SortSelect
published: string;
}[] = [];
let comments = this.state.searchResponse.comments.map(e => {
- return { type_: 'comments', data: e, published: e.comment.published };
+ return { type_: "comments", data: e, published: e.comment.published };
});
let posts = this.state.searchResponse.posts.map(e => {
- return { type_: 'posts', data: e, published: e.post.published };
+ return { type_: "posts", data: e, published: e.post.published };
});
let communities = this.state.searchResponse.communities.map(e => {
return {
- type_: 'communities',
+ type_: "communities",
data: e,
published: e.community.published,
};
});
let users = this.state.searchResponse.users.map(e => {
- return { type_: 'users', data: e, published: e.user.published };
+ return { type_: "users", data: e, published: e.user.published };
});
combined.push(...comments);
{combined.map(i => (
<div class="row">
<div class="col-12">
- {i.type_ == 'posts' && (
+ {i.type_ == "posts" && (
<PostListing
key={(i.data as PostView).post.id}
post_view={i.data as PostView}
enableNsfw={this.state.site.enable_nsfw}
/>
)}
- {i.type_ == 'comments' && (
+ {i.type_ == "comments" && (
<CommentNodes
key={(i.data as CommentView).comment.id}
nodes={[{ comment_view: i.data as CommentView }]}
enableDownvotes={this.state.site.enable_downvotes}
/>
)}
- {i.type_ == 'communities' && (
+ {i.type_ == "communities" && (
<div>{this.communityListing(i.data as CommunityView)}</div>
)}
- {i.type_ == 'users' && (
+ {i.type_ == "users" && (
<div>{this.userListing(i.data as UserViewSafe)}</div>
)}
</div>
<CommunityLink community={community_view.community} />
</span>
<span>{` -
- ${i18n.t('number_of_subscribers', {
+ ${i18n.t("number_of_subscribers", {
count: community_view.counts.subscribers,
})}
`}</span>
<span>
<UserListing user={user_view.user} showApubName />
</span>,
- <span>{` - ${i18n.t('number_of_comments', {
+ <span>{` - ${i18n.t("number_of_comments", {
count: user_view.counts.comment_count,
})}`}</span>,
];
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
)}
</div>
auth: authField(false),
};
- if (this.state.q != '') {
+ if (this.state.q != "") {
WebSocketService.Instance.send(wsClient.search(form));
}
}
console.log(msg);
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
return;
} else if (op == UserOperation.Search) {
let data = wsJsonToRes<SearchResponse>(msg).data;
-import { Component, linkEvent } from 'inferno';
-import { Helmet } from 'inferno-helmet';
-import { Subscription } from 'rxjs';
-import { retryWhen, delay, take } from 'rxjs/operators';
-import { Register, LoginResponse, UserOperation } from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
-import { wsUserOp, wsJsonToRes, toast, wsClient } from '../utils';
-import { SiteForm } from './site-form';
-import { Spinner } from './icon';
-import { i18n } from '../i18next';
+import { Component, linkEvent } from "inferno";
+import { Helmet } from "inferno-helmet";
+import { Subscription } from "rxjs";
+import { retryWhen, delay, take } from "rxjs/operators";
+import { Register, LoginResponse, UserOperation } from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
+import { wsUserOp, wsJsonToRes, toast, wsClient } from "../utils";
+import { SiteForm } from "./site-form";
+import { Spinner } from "./icon";
+import { i18n } from "../i18next";
interface State {
userForm: Register;
password_verify: undefined,
show_nsfw: true,
// The first admin signup doesn't need a captcha
- captcha_uuid: '',
- captcha_answer: '',
+ captcha_uuid: "",
+ captcha_answer: "",
},
doneRegisteringUser: false,
userLoading: false,
.subscribe(
msg => this.parseMessage(msg),
err => console.error(err),
- () => console.log('complete')
+ () => console.log("complete")
);
}
}
get documentTitle(): string {
- return `${i18n.t('setup')} - Lemmy`;
+ return `${i18n.t("setup")} - Lemmy`;
}
render() {
<Helmet title={this.documentTitle} />
<div class="row">
<div class="col-12 offset-lg-3 col-lg-6">
- <h3>{i18n.t('lemmy_instance_setup')}</h3>
+ <h3>{i18n.t("lemmy_instance_setup")}</h3>
{!this.state.doneRegisteringUser ? (
this.registerUser()
) : (
registerUser() {
return (
<form onSubmit={linkEvent(this, this.handleRegisterSubmit)}>
- <h5>{i18n.t('setup_admin')}</h5>
+ <h5>{i18n.t("setup_admin")}</h5>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="username">
- {i18n.t('username')}
+ {i18n.t("username")}
</label>
<div class="col-sm-10">
<input
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="email">
- {i18n.t('email')}
+ {i18n.t("email")}
</label>
<div class="col-sm-10">
type="email"
id="email"
class="form-control"
- placeholder={i18n.t('optional')}
+ placeholder={i18n.t("optional")}
value={this.state.userForm.email}
onInput={linkEvent(this, this.handleRegisterEmailChange)}
minLength={3}
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="password">
- {i18n.t('password')}
+ {i18n.t("password")}
</label>
<div class="col-sm-10">
<input
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label" htmlFor="verify-password">
- {i18n.t('verify_password')}
+ {i18n.t("verify_password")}
</label>
<div class="col-sm-10">
<input
<div class="form-group row">
<div class="col-sm-10">
<button type="submit" class="btn btn-secondary">
- {this.state.userLoading ? <Spinner /> : i18n.t('sign_up')}
+ {this.state.userLoading ? <Spinner /> : i18n.t("sign_up")}
</button>
</div>
</div>
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
+ toast(i18n.t(msg.error), "danger");
this.state.userLoading = false;
this.setState(this.state);
return;
UserService.Instance.login(data);
this.setState(this.state);
} else if (op == UserOperation.CreateSite) {
- window.location.href = '/';
+ window.location.href = "/";
}
}
}
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
import {
CommunityView,
CommunityModeratorView,
UserViewSafe,
AddModToCommunity,
Category,
-} from 'lemmy-js-client';
-import { WebSocketService, UserService } from '../services';
-import { mdToHtml, getUnixTime, wsClient, authField } from '../utils';
-import { CommunityForm } from './community-form';
-import { UserListing } from './user-listing';
-import { CommunityLink } from './community-link';
-import { BannerIconHeader } from './banner-icon-header';
-import { Icon } from './icon';
-import { i18n } from '../i18next';
+} from "lemmy-js-client";
+import { WebSocketService, UserService } from "../services";
+import { mdToHtml, getUnixTime, wsClient, authField } from "../utils";
+import { CommunityForm } from "./community-form";
+import { UserListing } from "./user-listing";
+import { CommunityLink } from "./community-link";
+import { BannerIconHeader } from "./banner-icon-header";
+import { Icon } from "./icon";
+import { i18n } from "../i18next";
interface SidebarProps {
community_view: CommunityView;
onClick={linkEvent(community.id, this.handleUnsubscribe)}
>
<Icon icon="check" classes="icon-inline text-success mr-1" />
- {i18n.t('joined')}
+ {i18n.t("joined")}
</a>
)}
{community.removed && (
<small className="mr-2 text-muted font-italic">
- {i18n.t('removed')}
+ {i18n.t("removed")}
</small>
)}
{community.deleted && (
<small className="mr-2 text-muted font-italic">
- {i18n.t('deleted')}
+ {i18n.t("deleted")}
</small>
)}
{community.nsfw && (
<small className="mr-2 text-muted font-italic">
- {i18n.t('nsfw')}
+ {i18n.t("nsfw")}
</small>
)}
</h5>
return (
<ul class="my-1 list-inline">
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_online', { count: this.props.online })}
+ {i18n.t("number_online", { count: this.props.online })}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_day,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('day')}`}
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("day")}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_day,
- })}{' '}
- / {i18n.t('day')}
+ })}{" "}
+ / {i18n.t("day")}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_week,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('week')}`}
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("week")}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_week,
- })}{' '}
- / {i18n.t('week')}
+ })}{" "}
+ / {i18n.t("week")}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_month,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('month')}`}
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("month")}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_month,
- })}{' '}
- / {i18n.t('month')}
+ })}{" "}
+ / {i18n.t("month")}
</li>
<li
className="list-inline-item badge badge-secondary pointer"
- data-tippy-content={`${i18n.t('number_of_users', {
+ data-tippy-content={`${i18n.t("number_of_users", {
count: counts.users_active_half_year,
- })} ${i18n.t('active_in_the_last')} ${i18n.t('number_of_months', {
+ })} ${i18n.t("active_in_the_last")} ${i18n.t("number_of_months", {
count: 6,
})}`}
>
- {i18n.t('number_of_users', {
+ {i18n.t("number_of_users", {
count: counts.users_active_half_year,
- })}{' '}
- / {i18n.t('number_of_months', { count: 6 })}
+ })}{" "}
+ / {i18n.t("number_of_months", { count: 6 })}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_subscribers', {
+ {i18n.t("number_of_subscribers", {
count: counts.subscribers,
})}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_posts', {
+ {i18n.t("number_of_posts", {
count: counts.posts,
})}
</li>
<li className="list-inline-item badge badge-secondary">
- {i18n.t('number_of_comments', {
+ {i18n.t("number_of_comments", {
count: counts.comments,
})}
</li>
className="badge badge-secondary"
to={`/modlog/community/${this.props.community_view.community.id}`}
>
- {i18n.t('modlog')}
+ {i18n.t("modlog")}
</Link>
</li>
</ul>
mods() {
return (
<ul class="list-inline small">
- <li class="list-inline-item">{i18n.t('mods')}: </li>
+ <li class="list-inline-item">{i18n.t("mods")}: </li>
{this.props.moderators.map(mod => (
<li class="list-inline-item">
<UserListing user={mod.moderator} />
<Link
className={`btn btn-secondary btn-block mb-2 ${
community_view.community.deleted || community_view.community.removed
- ? 'no-click'
- : ''
+ ? "no-click"
+ : ""
}`}
to={`/create_post?community_id=${community_view.community.id}`}
>
- {i18n.t('create_a_post')}
+ {i18n.t("create_a_post")}
</Link>
)
);
this.handleSubscribe
)}
>
- {i18n.t('subscribe')}
+ {i18n.t("subscribe")}
</a>
)}
</div>
role="button"
class="pointer"
onClick={linkEvent(this, this.handleEditClick)}
- data-tippy-content={i18n.t('edit')}
- aria-label={i18n.t('edit')}
+ data-tippy-content={i18n.t("edit")}
+ aria-label={i18n.t("edit")}
>
<Icon icon="edit" classes="icon-inline" />
</span>
this.handleShowConfirmLeaveModTeamClick
)}
>
- {i18n.t('leave_mod_team')}
+ {i18n.t("leave_mod_team")}
</span>
</li>
) : (
<>
<li className="list-inline-item-action">
- {i18n.t('are_you_sure')}
+ {i18n.t("are_you_sure")}
</li>
<li className="list-inline-item-action">
<span
role="button"
onClick={linkEvent(this, this.handleLeaveModTeamClick)}
>
- {i18n.t('yes')}
+ {i18n.t("yes")}
</span>
</li>
<li className="list-inline-item-action">
this.handleCancelLeaveModTeamClick
)}
>
- {i18n.t('no')}
+ {i18n.t("no")}
</span>
</li>
</>
onClick={linkEvent(this, this.handleDeleteClick)}
data-tippy-content={
!community_view.community.deleted
- ? i18n.t('delete')
- : i18n.t('restore')
+ ? i18n.t("delete")
+ : i18n.t("restore")
}
aria-label={
!community_view.community.deleted
- ? i18n.t('delete')
- : i18n.t('restore')
+ ? i18n.t("delete")
+ : i18n.t("restore")
}
>
<Icon
icon="trash"
classes={`icon-inline ${
- community_view.community.deleted && 'text-danger'
+ community_view.community.deleted && "text-danger"
}`}
/>
</span>
role="button"
onClick={linkEvent(this, this.handleModRemoveShow)}
>
- {i18n.t('remove')}
+ {i18n.t("remove")}
</span>
) : (
<span
role="button"
onClick={linkEvent(this, this.handleModRemoveSubmit)}
>
- {i18n.t('restore')}
+ {i18n.t("restore")}
</span>
)}
</li>
<form onSubmit={linkEvent(this, this.handleModRemoveSubmit)}>
<div class="form-group row">
<label class="col-form-label" htmlFor="remove-reason">
- {i18n.t('reason')}
+ {i18n.t("reason")}
</label>
<input
type="text"
id="remove-reason"
class="form-control mr-2"
- placeholder={i18n.t('optional')}
+ placeholder={i18n.t("optional")}
value={this.state.removeReason}
onInput={linkEvent(this, this.handleModRemoveReasonChange)}
/>
{/* </div> */}
<div class="form-group row">
<button type="submit" class="btn btn-secondary">
- {i18n.t('remove_community')}
+ {i18n.t("remove_community")}
</button>
</div>
</form>
-import { Component, linkEvent } from 'inferno';
-import { Prompt } from 'inferno-router';
-import { MarkdownTextArea } from './markdown-textarea';
-import { Spinner } from './icon';
-import { ImageUploadForm } from './image-upload-form';
-import { Site, EditSite } from 'lemmy-js-client';
-import { WebSocketService } from '../services';
+import { Component, linkEvent } from "inferno";
+import { Prompt } from "inferno-router";
+import { MarkdownTextArea } from "./markdown-textarea";
+import { Spinner } from "./icon";
+import { ImageUploadForm } from "./image-upload-form";
+import { Site, EditSite } from "lemmy-js-client";
+import { WebSocketService } from "../services";
import {
authField,
capitalizeFirstLetter,
randomStr,
wsClient,
-} from '../utils';
-import { i18n } from '../i18next';
+} from "../utils";
+import { i18n } from "../i18next";
interface SiteFormProps {
site?: Site; // If a site is given, that means this is an edit
!this.props.site &&
(this.state.siteForm.name || this.state.siteForm.description)
}
- message={i18n.t('block_leaving')}
+ message={i18n.t("block_leaving")}
/>
<form onSubmit={linkEvent(this, this.handleCreateSiteSubmit)}>
<h5>{`${
this.props.site
- ? capitalizeFirstLetter(i18n.t('save'))
- : capitalizeFirstLetter(i18n.t('name'))
- } ${i18n.t('your_site')}`}</h5>
+ ? capitalizeFirstLetter(i18n.t("save"))
+ : capitalizeFirstLetter(i18n.t("name"))
+ } ${i18n.t("your_site")}`}</h5>
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor="create-site-name">
- {i18n.t('name')}
+ {i18n.t("name")}
</label>
<div class="col-12">
<input
</div>
</div>
<div class="form-group">
- <label>{i18n.t('icon')}</label>
+ <label>{i18n.t("icon")}</label>
<ImageUploadForm
- uploadTitle={i18n.t('upload_icon')}
+ uploadTitle={i18n.t("upload_icon")}
imageSrc={this.state.siteForm.icon}
onUpload={this.handleIconUpload}
onRemove={this.handleIconRemove}
/>
</div>
<div class="form-group">
- <label>{i18n.t('banner')}</label>
+ <label>{i18n.t("banner")}</label>
<ImageUploadForm
- uploadTitle={i18n.t('upload_banner')}
+ uploadTitle={i18n.t("upload_banner")}
imageSrc={this.state.siteForm.banner}
onUpload={this.handleBannerUpload}
onRemove={this.handleBannerRemove}
</div>
<div class="form-group row">
<label class="col-12 col-form-label" htmlFor={this.id}>
- {i18n.t('sidebar')}
+ {i18n.t("sidebar")}
</label>
<div class="col-12">
<MarkdownTextArea
)}
/>
<label class="form-check-label" htmlFor="create-site-downvotes">
- {i18n.t('enable_downvotes')}
+ {i18n.t("enable_downvotes")}
</label>
</div>
</div>
class="form-check-label"
htmlFor="create-site-enable-nsfw"
>
- {i18n.t('enable_nsfw')}
+ {i18n.t("enable_nsfw")}
</label>
</div>
</div>
class="form-check-label"
htmlFor="create-site-open-registration"
>
- {i18n.t('open_registration')}
+ {i18n.t("open_registration")}
</label>
</div>
</div>
{this.state.loading ? (
<Spinner />
) : this.props.site ? (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
) : (
- capitalizeFirstLetter(i18n.t('create'))
+ capitalizeFirstLetter(i18n.t("create"))
)}
</button>
{this.props.site && (
class="btn btn-secondary"
onClick={linkEvent(this, this.handleCancel)}
>
- {i18n.t('cancel')}
+ {i18n.t("cancel")}
</button>
)}
</div>
}
handleIconRemove() {
- this.state.siteForm.icon = '';
+ this.state.siteForm.icon = "";
this.setState(this.state);
}
}
handleBannerRemove() {
- this.state.siteForm.banner = '';
+ this.state.siteForm.banner = "";
this.setState(this.state);
}
}
-import { Component, linkEvent } from 'inferno';
-import { SortType } from 'lemmy-js-client';
-import { sortingHelpUrl, randomStr } from '../utils';
-import { Icon } from './icon';
-import { i18n } from '../i18next';
+import { Component, linkEvent } from "inferno";
+import { SortType } from "lemmy-js-client";
+import { sortingHelpUrl, randomStr } from "../utils";
+import { Icon } from "./icon";
+import { i18n } from "../i18next";
interface SortSelectProps {
sort: SortType;
value={this.state.sort}
onChange={linkEvent(this, this.handleSortChange)}
class="custom-select w-auto mr-2 mb-2"
- aria-label={i18n.t('sort_type')}
+ aria-label={i18n.t("sort_type")}
>
<option disabled aria-hidden="true">
- {i18n.t('sort_type')}
+ {i18n.t("sort_type")}
</option>
{!this.props.hideHot && [
- <option value={SortType.Hot}>{i18n.t('hot')}</option>,
- <option value={SortType.Active}>{i18n.t('active')}</option>,
+ <option value={SortType.Hot}>{i18n.t("hot")}</option>,
+ <option value={SortType.Active}>{i18n.t("active")}</option>,
]}
- <option value={SortType.New}>{i18n.t('new')}</option>
+ <option value={SortType.New}>{i18n.t("new")}</option>
{!this.props.hideMostComments && [
<option value={SortType.MostComments}>
- {i18n.t('most_comments')}
+ {i18n.t("most_comments")}
</option>,
<option value={SortType.NewComments}>
- {i18n.t('new_comments')}
+ {i18n.t("new_comments")}
</option>,
]}
<option disabled aria-hidden="true">
─────
</option>
- <option value={SortType.TopDay}>{i18n.t('top_day')}</option>
- <option value={SortType.TopWeek}>{i18n.t('top_week')}</option>
- <option value={SortType.TopMonth}>{i18n.t('top_month')}</option>
- <option value={SortType.TopYear}>{i18n.t('top_year')}</option>
- <option value={SortType.TopAll}>{i18n.t('top_all')}</option>
+ <option value={SortType.TopDay}>{i18n.t("top_day")}</option>
+ <option value={SortType.TopWeek}>{i18n.t("top_week")}</option>
+ <option value={SortType.TopMonth}>{i18n.t("top_month")}</option>
+ <option value={SortType.TopYear}>{i18n.t("top_year")}</option>
+ <option value={SortType.TopAll}>{i18n.t("top_all")}</option>
</select>
<a
className="text-muted"
href={sortingHelpUrl}
rel="noopener"
- title={i18n.t('sorting_help')}
+ title={i18n.t("sorting_help")}
>
<Icon icon="help-circle" classes="icon-inline" />
</a>
// Custom css
-@import '../../../node_modules/tributejs/dist/tribute.css';
-@import '../../../node_modules/toastify-js/src/toastify.css';
-@import '../../../node_modules/choices.js/src/styles/choices.scss';
-@import '../../../node_modules/tippy.js/dist/tippy.css';
-@import '../../assets/css/main.css';
+@import "../../../node_modules/tributejs/dist/tribute.css";
+@import "../../../node_modules/toastify-js/src/toastify.css";
+@import "../../../node_modules/choices.js/src/styles/choices.scss";
+@import "../../../node_modules/tippy.js/dist/tippy.css";
+@import "../../assets/css/main.css";
-import { Component } from 'inferno';
+import { Component } from "inferno";
export class Symbols extends Component<any, any> {
constructor(props: any, context: any) {
<svg
aria-hidden="true"
style={{
- position: 'absolute',
+ position: "absolute",
width: 0,
height: 0,
- overflow: 'hidden',
+ overflow: "hidden",
}}
version="1.1"
xmlns="http://www.w3.org/2000/svg"
-import { UserSafeSettings } from 'lemmy-js-client';
-import { Helmet } from 'inferno-helmet';
-import { Component } from 'inferno';
+import { UserSafeSettings } from "lemmy-js-client";
+import { Helmet } from "inferno-helmet";
+import { Component } from "inferno";
interface Props {
user: UserSafeSettings | undefined;
export class Theme extends Component<Props> {
render() {
const { user } = this.props;
- const hasUserTheme = user && user.theme !== 'browser';
+ const hasUserTheme = user && user.theme !== "browser";
return (
<Helmet>
-import { Component, linkEvent } from 'inferno';
-import { i18n } from '../i18next';
+import { Component, linkEvent } from "inferno";
+import { i18n } from "../i18next";
import {
PostView,
CommentView,
SortType,
GetUserDetailsResponse,
UserViewSafe,
-} from 'lemmy-js-client';
-import { UserDetailsView } from '../interfaces';
-import { commentsToFlatNodes, setupTippy } from '../utils';
-import { PostListing } from './post-listing';
-import { CommentNodes } from './comment-nodes';
+} from "lemmy-js-client";
+import { UserDetailsView } from "../interfaces";
+import { commentsToFlatNodes, setupTippy } from "../utils";
+import { PostListing } from "./post-listing";
+import { CommentNodes } from "./comment-nodes";
interface UserDetailsProps {
userRes: GetUserDetailsResponse;
class="btn btn-secondary mr-1"
onClick={linkEvent(this, this.prevPage)}
>
- {i18n.t('prev')}
+ {i18n.t("prev")}
</button>
)}
{this.props.userRes.comments.length + this.props.userRes.posts.length >
class="btn btn-secondary"
onClick={linkEvent(this, this.nextPage)}
>
- {i18n.t('next')}
+ {i18n.t("next")}
</button>
)}
</div>
-import { Component } from 'inferno';
-import { Link } from 'inferno-router';
-import { UserSafe } from 'lemmy-js-client';
-import { showAvatars, hostname, isCakeDay } from '../utils';
-import { CakeDay } from './cake-day';
-import { PictrsImage } from './pictrs-image';
+import { Component } from "inferno";
+import { Link } from "inferno-router";
+import { UserSafe } from "lemmy-js-client";
+import { showAvatars, hostname, isCakeDay } from "../utils";
+import { CakeDay } from "./cake-day";
+import { PictrsImage } from "./pictrs-image";
interface UserListingProps {
user: UserSafe;
<>
<Link
title={apubName}
- className={this.props.muted ? 'text-muted' : 'text-info'}
+ className={this.props.muted ? "text-muted" : "text-info"}
to={link}
>
{!this.props.hideAvatar && user.avatar && showAvatars() && (
-import { Component, linkEvent } from 'inferno';
-import { Link } from 'inferno-router';
-import { Subscription } from 'rxjs';
+import { Component, linkEvent } from "inferno";
+import { Link } from "inferno-router";
+import { Subscription } from "rxjs";
import {
UserOperation,
SortType,
CommentResponse,
PostResponse,
BanUserResponse,
-} from 'lemmy-js-client';
-import { InitialFetchRequest, UserDetailsView } from '../interfaces';
-import { WebSocketService, UserService } from '../services';
+} from "lemmy-js-client";
+import { InitialFetchRequest, UserDetailsView } from "../interfaces";
+import { WebSocketService, UserService } from "../services";
import {
wsJsonToRes,
fetchLimit,
setOptionalAuth,
saveScrollPosition,
restoreScrollPosition,
-} from '../utils';
-import { UserListing } from './user-listing';
-import { HtmlTags } from './html-tags';
-import { SortSelect } from './sort-select';
-import { ListingTypeSelect } from './listing-type-select';
-import { MomentTime } from './moment-time';
-import { i18n } from '../i18next';
-import moment from 'moment';
-import { UserDetails } from './user-details';
-import { MarkdownTextArea } from './markdown-textarea';
-import { Icon, Spinner } from './icon';
-import { ImageUploadForm } from './image-upload-form';
-import { BannerIconHeader } from './banner-icon-header';
-import { CommunityLink } from './community-link';
+} from "../utils";
+import { UserListing } from "./user-listing";
+import { HtmlTags } from "./html-tags";
+import { SortSelect } from "./sort-select";
+import { ListingTypeSelect } from "./listing-type-select";
+import { MomentTime } from "./moment-time";
+import { i18n } from "../i18next";
+import moment from "moment";
+import { UserDetails } from "./user-details";
+import { MarkdownTextArea } from "./markdown-textarea";
+import { Icon, Spinner } from "./icon";
+import { ImageUploadForm } from "./image-upload-form";
+import { BannerIconHeader } from "./banner-icon-header";
+import { CommunityLink } from "./community-link";
interface UserState {
userRes: GetUserDetailsResponse;
}
static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
- let pathSplit = req.path.split('/');
+ let pathSplit = req.path.split("/");
let promises: Promise<any>[] = [];
// It can be /u/me, or /username/1
componentDidUpdate(lastProps: any) {
// Necessary if you are on a post and you click another post (same route)
if (
- lastProps.location.pathname.split('/')[2] !==
- lastProps.history.location.pathname.split('/')[2]
+ lastProps.location.pathname.split("/")[2] !==
+ lastProps.history.location.pathname.split("/")[2]
) {
// Couldnt get a refresh working. This does for now.
location.reload();
<div class="btn-group btn-group-toggle flex-wrap mb-2">
<label
className={`btn btn-outline-secondary pointer
- ${this.state.view == UserDetailsView.Overview && 'active'}
+ ${this.state.view == UserDetailsView.Overview && "active"}
`}
>
<input
checked={this.state.view === UserDetailsView.Overview}
onChange={linkEvent(this, this.handleViewChange)}
/>
- {i18n.t('overview')}
+ {i18n.t("overview")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.view == UserDetailsView.Comments && 'active'}
+ ${this.state.view == UserDetailsView.Comments && "active"}
`}
>
<input
checked={this.state.view == UserDetailsView.Comments}
onChange={linkEvent(this, this.handleViewChange)}
/>
- {i18n.t('comments')}
+ {i18n.t("comments")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.view == UserDetailsView.Posts && 'active'}
+ ${this.state.view == UserDetailsView.Posts && "active"}
`}
>
<input
checked={this.state.view == UserDetailsView.Posts}
onChange={linkEvent(this, this.handleViewChange)}
/>
- {i18n.t('posts')}
+ {i18n.t("posts")}
</label>
<label
className={`btn btn-outline-secondary pointer
- ${this.state.view == UserDetailsView.Saved && 'active'}
+ ${this.state.view == UserDetailsView.Saved && "active"}
`}
>
<input
checked={this.state.view == UserDetailsView.Saved}
onChange={linkEvent(this, this.handleViewChange)}
/>
- {i18n.t('saved')}
+ {i18n.t("saved")}
</label>
</div>
);
</li>
{uv.user.banned && (
<li className="list-inline-item badge badge-danger">
- {i18n.t('banned')}
+ {i18n.t("banned")}
</li>
)}
</ul>
class="d-flex align-self-start btn btn-secondary mr-2"
onClick={linkEvent(this, this.handleLogoutClick)}
>
- {i18n.t('logout')}
+ {i18n.t("logout")}
</button>
) : (
<>
<a
className={`d-flex align-self-start btn btn-secondary mr-2 ${
- !uv.user.matrix_user_id && 'invisible'
+ !uv.user.matrix_user_id && "invisible"
}`}
rel="noopener"
href={`https://matrix.to/#/${uv.user.matrix_user_id}`}
>
- {i18n.t('send_secure_message')}
+ {i18n.t("send_secure_message")}
</a>
<Link
- className={'d-flex align-self-start btn btn-secondary'}
+ className={"d-flex align-self-start btn btn-secondary"}
to={`/create_private_message/recipient/${uv.user.id}`}
>
- {i18n.t('send_message')}
+ {i18n.t("send_message")}
</Link>
</>
)}
<div>
<ul class="list-inline mb-2">
<li className="list-inline-item badge badge-light">
- {i18n.t('number_of_posts', { count: uv.counts.post_count })}
+ {i18n.t("number_of_posts", { count: uv.counts.post_count })}
</li>
<li className="list-inline-item badge badge-light">
- {i18n.t('number_of_comments', {
+ {i18n.t("number_of_comments", {
count: uv.counts.comment_count,
})}
</li>
</ul>
</div>
<div class="text-muted">
- {i18n.t('joined')}{' '}
+ {i18n.t("joined")}{" "}
<MomentTime data={uv.user} showAgo ignoreUpdated />
</div>
<div className="d-flex align-items-center text-muted mb-2">
<Icon icon="cake" />
<span className="ml-2">
- {i18n.t('cake_day_title')}{' '}
- {moment.utc(uv.user.published).local().format('MMM DD, YYYY')}
+ {i18n.t("cake_day_title")}{" "}
+ {moment.utc(uv.user.published).local().format("MMM DD, YYYY")}
</span>
</div>
</div>
<div>
<div class="card border-secondary mb-3">
<div class="card-body">
- <h5>{i18n.t('settings')}</h5>
+ <h5>{i18n.t("settings")}</h5>
<form onSubmit={linkEvent(this, this.handleUserSettingsSubmit)}>
<div class="form-group">
- <label>{i18n.t('avatar')}</label>
+ <label>{i18n.t("avatar")}</label>
<ImageUploadForm
- uploadTitle={i18n.t('upload_avatar')}
+ uploadTitle={i18n.t("upload_avatar")}
imageSrc={this.state.userSettingsForm.avatar}
onUpload={this.handleAvatarUpload}
onRemove={this.handleAvatarRemove}
/>
</div>
<div class="form-group">
- <label>{i18n.t('banner')}</label>
+ <label>{i18n.t("banner")}</label>
<ImageUploadForm
- uploadTitle={i18n.t('upload_banner')}
+ uploadTitle={i18n.t("upload_banner")}
imageSrc={this.state.userSettingsForm.banner}
onUpload={this.handleBannerUpload}
onRemove={this.handleBannerRemove}
/>
</div>
<div class="form-group">
- <label htmlFor="user-language">{i18n.t('language')}</label>
+ <label htmlFor="user-language">{i18n.t("language")}</label>
<select
id="user-language"
value={this.state.userSettingsForm.lang}
class="ml-2 custom-select w-auto"
>
<option disabled aria-hidden="true">
- {i18n.t('language')}
+ {i18n.t("language")}
</option>
- <option value="browser">{i18n.t('browser_default')}</option>
+ <option value="browser">{i18n.t("browser_default")}</option>
<option disabled aria-hidden="true">
──
</option>
</select>
</div>
<div class="form-group">
- <label htmlFor="user-theme">{i18n.t('theme')}</label>
+ <label htmlFor="user-theme">{i18n.t("theme")}</label>
<select
id="user-theme"
value={this.state.userSettingsForm.theme}
class="ml-2 custom-select w-auto"
>
<option disabled aria-hidden="true">
- {i18n.t('theme')}
+ {i18n.t("theme")}
</option>
- <option value="browser">{i18n.t('browser_default')}</option>
+ <option value="browser">{i18n.t("browser_default")}</option>
{themes.map(theme => (
<option value={theme}>{theme}</option>
))}
</div>
<form className="form-group">
<label>
- <div class="mr-2">{i18n.t('sort_type')}</div>
+ <div class="mr-2">{i18n.t("sort_type")}</div>
</label>
<ListingTypeSelect
type_={
</form>
<form className="form-group">
<label>
- <div class="mr-2">{i18n.t('type')}</div>
+ <div class="mr-2">{i18n.t("type")}</div>
</label>
<SortSelect
sort={
</form>
<div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="display-name">
- {i18n.t('display_name')}
+ {i18n.t("display_name")}
</label>
<div class="col-lg-7">
<input
id="display-name"
type="text"
class="form-control"
- placeholder={i18n.t('optional')}
+ placeholder={i18n.t("optional")}
value={this.state.userSettingsForm.preferred_username}
onInput={linkEvent(
this,
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label" htmlFor="user-bio">
- {i18n.t('bio')}
+ {i18n.t("bio")}
</label>
<div class="col-lg-9">
<MarkdownTextArea
</div>
<div class="form-group row">
<label class="col-lg-3 col-form-label" htmlFor="user-email">
- {i18n.t('email')}
+ {i18n.t("email")}
</label>
<div class="col-lg-9">
<input
type="email"
id="user-email"
class="form-control"
- placeholder={i18n.t('optional')}
+ placeholder={i18n.t("optional")}
value={this.state.userSettingsForm.email}
onInput={linkEvent(
this,
<div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="matrix-user-id">
<a href={elementUrl} rel="noopener">
- {i18n.t('matrix_user_id')}
+ {i18n.t("matrix_user_id")}
</a>
</label>
<div class="col-lg-7">
</div>
<div class="form-group row">
<label class="col-lg-5 col-form-label" htmlFor="user-password">
- {i18n.t('new_password')}
+ {i18n.t("new_password")}
</label>
<div class="col-lg-7">
<input
class="col-lg-5 col-form-label"
htmlFor="user-verify-password"
>
- {i18n.t('verify_password')}
+ {i18n.t("verify_password")}
</label>
<div class="col-lg-7">
<input
class="col-lg-5 col-form-label"
htmlFor="user-old-password"
>
- {i18n.t('old_password')}
+ {i18n.t("old_password")}
</label>
<div class="col-lg-7">
<input
)}
/>
<label class="form-check-label" htmlFor="user-show-nsfw">
- {i18n.t('show_nsfw')}
+ {i18n.t("show_nsfw")}
</label>
</div>
</div>
)}
/>
<label class="form-check-label" htmlFor="user-show-avatars">
- {i18n.t('show_avatars')}
+ {i18n.t("show_avatars")}
</label>
</div>
</div>
class="form-check-label"
htmlFor="user-send-notifications-to-email"
>
- {i18n.t('send_notifications_to_email')}
+ {i18n.t("send_notifications_to_email")}
</label>
</div>
</div>
{this.state.userSettingsLoading ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t('save'))
+ capitalizeFirstLetter(i18n.t("save"))
)}
</button>
</div>
this.handleDeleteAccountShowConfirmToggle
)}
>
- {i18n.t('delete_account')}
+ {i18n.t("delete_account")}
</button>
{this.state.deleteAccountShowConfirm && (
<>
<div class="my-2 alert alert-danger" role="alert">
- {i18n.t('delete_account_confirm')}
+ {i18n.t("delete_account_confirm")}
</div>
<input
type="password"
{this.state.deleteAccountLoading ? (
<Spinner />
) : (
- capitalizeFirstLetter(i18n.t('delete'))
+ capitalizeFirstLetter(i18n.t("delete"))
)}
</button>
<button
this.handleDeleteAccountShowConfirmToggle
)}
>
- {i18n.t('cancel')}
+ {i18n.t("cancel")}
</button>
</>
)}
{this.state.userRes.moderates.length > 0 && (
<div class="card border-secondary mb-3">
<div class="card-body">
- <h5>{i18n.t('moderates')}</h5>
+ <h5>{i18n.t("moderates")}</h5>
<ul class="list-unstyled mb-0">
{this.state.userRes.moderates.map(cmv => (
<li>
{this.state.userRes.follows.length > 0 && (
<div class="card border-secondary mb-3">
<div class="card-body">
- <h5>{i18n.t('subscribed')}</h5>
+ <h5>{i18n.t("subscribed")}</h5>
<ul class="list-unstyled mb-0">
{this.state.userRes.follows.map(cfv => (
<li>
}
handleAvatarRemove() {
- this.state.userSettingsForm.avatar = '';
+ this.state.userSettingsForm.avatar = "";
this.setState(this.state);
}
}
handleBannerRemove() {
- this.state.userSettingsForm.banner = '';
+ this.state.userSettingsForm.banner = "";
this.setState(this.state);
}
handleUserSettingsMatrixUserIdChange(i: User, event: any) {
i.state.userSettingsForm.matrix_user_id = event.target.value;
if (
- i.state.userSettingsForm.matrix_user_id == '' &&
+ i.state.userSettingsForm.matrix_user_id == "" &&
!i.state.userRes.user_view.user.matrix_user_id
) {
i.state.userSettingsForm.matrix_user_id = undefined;
handleUserSettingsNewPasswordChange(i: User, event: any) {
i.state.userSettingsForm.new_password = event.target.value;
- if (i.state.userSettingsForm.new_password == '') {
+ if (i.state.userSettingsForm.new_password == "") {
i.state.userSettingsForm.new_password = undefined;
}
i.setState(i.state);
handleUserSettingsNewPasswordVerifyChange(i: User, event: any) {
i.state.userSettingsForm.new_password_verify = event.target.value;
- if (i.state.userSettingsForm.new_password_verify == '') {
+ if (i.state.userSettingsForm.new_password_verify == "") {
i.state.userSettingsForm.new_password_verify = undefined;
}
i.setState(i.state);
handleUserSettingsOldPasswordChange(i: User, event: any) {
i.state.userSettingsForm.old_password = event.target.value;
- if (i.state.userSettingsForm.old_password == '') {
+ if (i.state.userSettingsForm.old_password == "") {
i.state.userSettingsForm.old_password = undefined;
}
i.setState(i.state);
handleLogoutClick(i: User) {
UserService.Instance.logout();
- i.context.router.history.push('/');
+ i.context.router.history.push("/");
}
handleDeleteAccount(i: User, event: any) {
UserService.Instance.user.show_nsfw;
this.state.userSettingsForm.theme = UserService.Instance.user.theme
? UserService.Instance.user.theme
- : 'browser';
+ : "browser";
this.state.userSettingsForm.default_sort_type =
UserService.Instance.user.default_sort_type;
this.state.userSettingsForm.default_listing_type =
parseMessage(msg: any) {
let op = wsUserOp(msg);
if (msg.error) {
- toast(i18n.t(msg.error), 'danger');
- if (msg.error == 'couldnt_find_that_username_or_email') {
- this.context.router.history.push('/');
+ toast(i18n.t(msg.error), "danger");
+ if (msg.error == "couldnt_find_that_username_or_email") {
+ this.context.router.history.push("/");
}
this.setState({
deleteAccountLoading: false,
deleteAccountLoading: false,
deleteAccountShowConfirm: false,
});
- this.context.router.history.push('/');
+ this.context.router.history.push("/");
} else if (op == UserOperation.AddAdmin) {
let data = wsJsonToRes<AddAdminResponse>(msg).data;
this.state.siteRes.admins = data.admins;
UserService.Instance.user &&
data.comment_view.creator.id == UserService.Instance.user.id
) {
- toast(i18n.t('reply_sent'));
+ toast(i18n.t("reply_sent"));
}
} else if (op == UserOperation.SaveComment) {
let data = wsJsonToRes<CommentResponse>(msg).data;
-import { isBrowser } from './utils';
+import { isBrowser } from "./utils";
-const testHost = 'localhost:8536';
+const testHost = "localhost:8536";
let internalHost =
(!isBrowser() && process.env.LEMMY_INTERNAL_HOST) || testHost; // used for local dev
if (isBrowser()) {
// browser
const lemmyConfig =
- typeof window.lemmyConfig !== 'undefined' ? window.lemmyConfig : {};
+ typeof window.lemmyConfig !== "undefined" ? window.lemmyConfig : {};
externalHost = `${window.location.hostname}${
- ['1234', '1235'].includes(window.location.port)
- ? ':8536'
- : window.location.port == ''
- ? ''
+ ["1234", "1235"].includes(window.location.port)
+ ? ":8536"
+ : window.location.port == ""
+ ? ""
: `:${window.location.port}`
}`;
host = externalHost;
wsHost = lemmyConfig.wsHost || host;
- secure = window.location.protocol == 'https:' ? 's' : '';
+ secure = window.location.protocol == "https:" ? "s" : "";
} else {
// server-side
externalHost = process.env.LEMMY_EXTERNAL_HOST || testHost;
host = internalHost;
wsHost = process.env.LEMMY_WS_HOST || host;
- secure = process.env.LEMMY_HTTPS == 'true' ? 's' : '';
+ secure = process.env.LEMMY_HTTPS == "true" ? "s" : "";
}
const httpBase = `http://${host}`; // Don't use secure here
console.log(`wsUri: ${wsUri}`);
// This is for html tags, don't include port
-const httpExternalUri = `http${secure}://${externalHost.split(':')[0]}`;
+const httpExternalUri = `http${secure}://${externalHost.split(":")[0]}`;
export function httpExternalPath(path: string) {
return `${httpExternalUri}${path}`;
}
-import i18next from 'i18next';
-import { getLanguage } from './utils';
-import { en } from './translations/en';
-import { el } from './translations/el';
-import { eu } from './translations/eu';
-import { eo } from './translations/eo';
-import { es } from './translations/es';
-import { de } from './translations/de';
-import { fr } from './translations/fr';
-import { sv } from './translations/sv';
-import { ru } from './translations/ru';
-import { zh } from './translations/zh';
-import { nl } from './translations/nl';
-import { it } from './translations/it';
-import { fi } from './translations/fi';
-import { ca } from './translations/ca';
-import { fa } from './translations/fa';
-import { hi } from './translations/hi';
-import { pl } from './translations/pl';
-import { pt_BR } from './translations/pt_BR';
-import { ja } from './translations/ja';
-import { ka } from './translations/ka';
-import { gl } from './translations/gl';
-import { tr } from './translations/tr';
-import { hu } from './translations/hu';
-import { uk } from './translations/uk';
-import { sq } from './translations/sq';
-import { km } from './translations/km';
-import { ga } from './translations/ga';
-import { sr_Latn } from './translations/sr_Latn';
-import { da } from './translations/da';
-import { oc } from './translations/oc';
-import { hr } from './translations/hr';
+import i18next from "i18next";
+import { getLanguage } from "./utils";
+import { en } from "./translations/en";
+import { el } from "./translations/el";
+import { eu } from "./translations/eu";
+import { eo } from "./translations/eo";
+import { es } from "./translations/es";
+import { de } from "./translations/de";
+import { fr } from "./translations/fr";
+import { sv } from "./translations/sv";
+import { ru } from "./translations/ru";
+import { zh } from "./translations/zh";
+import { nl } from "./translations/nl";
+import { it } from "./translations/it";
+import { fi } from "./translations/fi";
+import { ca } from "./translations/ca";
+import { fa } from "./translations/fa";
+import { hi } from "./translations/hi";
+import { pl } from "./translations/pl";
+import { pt_BR } from "./translations/pt_BR";
+import { ja } from "./translations/ja";
+import { ka } from "./translations/ka";
+import { gl } from "./translations/gl";
+import { tr } from "./translations/tr";
+import { hu } from "./translations/hu";
+import { uk } from "./translations/uk";
+import { sq } from "./translations/sq";
+import { km } from "./translations/km";
+import { ga } from "./translations/ga";
+import { sr_Latn } from "./translations/sr_Latn";
+import { da } from "./translations/da";
+import { oc } from "./translations/oc";
+import { hr } from "./translations/hr";
// https://github.com/nimbusec-oss/inferno-i18next/blob/master/tests/T.test.js#L66
const resources = {
};
function format(value: any, format: any): any {
- return format === 'uppercase' ? value.toUpperCase() : value;
+ return format === "uppercase" ? value.toUpperCase() : value;
}
i18next.init({
// initImmediate: false,
lng: getLanguage(),
- fallbackLng: 'en',
+ fallbackLng: "en",
resources,
interpolation: { format },
});
-import { GetSiteResponse } from 'lemmy-js-client';
-import { UserService } from './services';
-import { i18n } from './i18next';
-import { getLanguage } from './utils';
+import { GetSiteResponse } from "lemmy-js-client";
+import { UserService } from "./services";
+import { i18n } from "./i18next";
+import { getLanguage } from "./utils";
export function initializeSite(site: GetSiteResponse) {
UserService.Instance.user = site.my_user;
GetSiteResponse,
LemmyHttp,
UserMentionView,
-} from 'lemmy-js-client';
+} from "lemmy-js-client";
export interface IsoData {
path: string;
-import { IRouteProps } from 'inferno-router/dist/Route';
-import { Main } from './components/main';
-import { Login } from './components/login';
-import { CreatePost } from './components/create-post';
-import { CreateCommunity } from './components/create-community';
-import { CreatePrivateMessage } from './components/create-private-message';
-import { PasswordChange } from './components/password_change';
-import { Post } from './components/post';
-import { Community } from './components/community';
-import { Communities } from './components/communities';
-import { User } from './components/user';
-import { Modlog } from './components/modlog';
-import { Setup } from './components/setup';
-import { AdminSettings } from './components/admin-settings';
-import { Inbox } from './components/inbox';
-import { Search } from './components/search';
-import { Instances } from './components/instances';
-import { InitialFetchRequest } from './interfaces';
+import { IRouteProps } from "inferno-router/dist/Route";
+import { Main } from "./components/main";
+import { Login } from "./components/login";
+import { CreatePost } from "./components/create-post";
+import { CreateCommunity } from "./components/create-community";
+import { CreatePrivateMessage } from "./components/create-private-message";
+import { PasswordChange } from "./components/password_change";
+import { Post } from "./components/post";
+import { Community } from "./components/community";
+import { Communities } from "./components/communities";
+import { User } from "./components/user";
+import { Modlog } from "./components/modlog";
+import { Setup } from "./components/setup";
+import { AdminSettings } from "./components/admin-settings";
+import { Inbox } from "./components/inbox";
+import { Search } from "./components/search";
+import { Instances } from "./components/instances";
+import { InitialFetchRequest } from "./interfaces";
interface IRoutePropsWithFetch extends IRouteProps {
fetchInitialData?(req: InitialFetchRequest): Promise<any>[];
// import Cookies from 'js-cookie';
-import IsomorphicCookie from 'isomorphic-cookie';
-import { UserSafeSettings, LoginResponse } from 'lemmy-js-client';
-import jwt_decode from 'jwt-decode';
-import { Subject, BehaviorSubject } from 'rxjs';
+import IsomorphicCookie from "isomorphic-cookie";
+import { UserSafeSettings, LoginResponse } from "lemmy-js-client";
+import jwt_decode from "jwt-decode";
+import { Subject, BehaviorSubject } from "rxjs";
interface Claims {
id: number;
this.setClaims(this.auth);
} else {
// setTheme();
- console.log('No JWT cookie found.');
+ console.log("No JWT cookie found.");
}
}
public login(res: LoginResponse) {
let expires = new Date();
expires.setDate(expires.getDate() + 365);
- IsomorphicCookie.save('jwt', res.jwt, { expires, secure: false });
- console.log('jwt cookie set');
+ IsomorphicCookie.save("jwt", res.jwt, { expires, secure: false });
+ console.log("jwt cookie set");
this.setClaims(res.jwt);
}
public logout() {
- IsomorphicCookie.remove('jwt', { secure: false });
+ IsomorphicCookie.remove("jwt", { secure: false });
this.claims = undefined;
this.user = undefined;
// setTheme();
this.jwtSub.next();
- console.log('Logged out.');
+ console.log("Logged out.");
}
public get auth(): string {
- return IsomorphicCookie.load('jwt');
+ return IsomorphicCookie.load("jwt");
}
private setClaims(jwt: string) {
-import { wsUri } from '../env';
-import { UserViewSafe, WebSocketJsonResponse } from 'lemmy-js-client';
-import { isBrowser } from '../utils';
-import { Observable } from 'rxjs';
-import { share } from 'rxjs/operators';
+import { wsUri } from "../env";
+import { UserViewSafe, WebSocketJsonResponse } from "lemmy-js-client";
+import { isBrowser } from "../utils";
+import { Observable } from "rxjs";
+import { share } from "rxjs/operators";
import {
Options as WSOptions,
default as ReconnectingWebSocket,
-} from 'reconnecting-websocket';
+} from "reconnecting-websocket";
export class WebSocketService {
private static _instance: WebSocketService;
-export { UserService } from './UserService';
-export { WebSocketService } from './WebSocketService';
+export { UserService } from "./UserService";
+export { WebSocketService } from "./WebSocketService";