diff --git a/.babelrc b/.babelrc index 2da0dea1..b96976f8 100644 --- a/.babelrc +++ b/.babelrc @@ -10,11 +10,11 @@ } } ], - ["@babel/typescript", {"isTSX": true, "allExtensions": true}] + ["@babel/typescript", { "isTSX": true, "allExtensions": true }] ], "plugins": [ "@babel/plugin-transform-runtime", - ["babel-plugin-inferno", { "imports": true }], - ["@babel/plugin-proposal-class-properties", { "loose": true }], + ["babel-plugin-inferno", { "imports": true }], + ["@babel/plugin-proposal-class-properties", { "loose": true }] ] } diff --git a/.eslintignore b/.eslintignore index 439fa035..26ddcb55 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,7 @@ generate_translations.js webpack.config.js src/api_tests +**/*.png +**/*.svg +**/*.css +**/*.scss \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 0c9a5f46..cc1bff1e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,9 +3,7 @@ "env": { "browser": true }, - "plugins": [ - "@typescript-eslint" - ], + "plugins": ["@typescript-eslint"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md index 83c2ffae..69b116fd 100644 --- a/.github/ISSUE_TEMPLATE/BUG_REPORT.md +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -1,10 +1,9 @@ --- name: "\U0001F41E Bug Report" about: Create a report to help us improve Lemmy -title: '' +title: "" labels: bug -assignees: '' - +assignees: "" --- Found a bug? Please fill out the sections below. 👍 @@ -15,7 +14,6 @@ For backend issues, use [lemmy](https://github.com/LemmyNet/lemmy) A summary of the bug. - ### Steps to Reproduce 1. (for example) I clicked login, and an endless spinner show up. @@ -24,6 +22,6 @@ A summary of the bug. ### Technical details -* Please post your log: `sudo docker-compose logs > lemmy_log.out`. -* What OS are you trying to install lemmy on? -* Any browser console errors? +- Please post your log: `sudo docker-compose logs > lemmy_log.out`. +- What OS are you trying to install lemmy on? +- Any browser console errors? diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md index 9886d8ad..bfeca29a 100644 --- a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -1,10 +1,9 @@ --- name: "\U0001F680 Feature request" about: Suggest an idea for improving Lemmy -title: '' +title: "" labels: enhancement -assignees: '' - +assignees: "" --- For backend issues, use [lemmy](https://github.com/LemmyNet/lemmy) diff --git a/.github/ISSUE_TEMPLATE/QUESTION.md b/.github/ISSUE_TEMPLATE/QUESTION.md index b45f8f1e..15325873 100644 --- a/.github/ISSUE_TEMPLATE/QUESTION.md +++ b/.github/ISSUE_TEMPLATE/QUESTION.md @@ -1,10 +1,9 @@ --- name: "? Question" about: General questions about Lemmy -title: '' +title: "" labels: question -assignees: '' - +assignees: "" --- What's the question you have about lemmy? diff --git a/.github/ISSUE_TEMPLATE/hexbear.md b/.github/ISSUE_TEMPLATE/hexbear.md index 3bb06239..65483df8 100644 --- a/.github/ISSUE_TEMPLATE/hexbear.md +++ b/.github/ISSUE_TEMPLATE/hexbear.md @@ -1,10 +1,9 @@ --- name: Hexbear about: For hexbear issues -title: '' +title: "" labels: hexbear -assignees: '' - +assignees: "" --- For hexbear-related issues diff --git a/.prettierignore b/.prettierignore index a14ae90e..e7a0d20e 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,2 @@ -src/shared/translations \ No newline at end of file +src/shared/translations +lemmy-translations \ No newline at end of file diff --git a/.woodpecker.yml b/.woodpecker.yml index d9e3fa7e..8d3c6f1c 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -69,7 +69,7 @@ pipeline: publish_release_docker_manifest: image: plugins/manifest - settings: + settings: username: from_secret: docker_username password: @@ -85,7 +85,7 @@ pipeline: publish_latest_release_docker_manifest: image: plugins/manifest - settings: + settings: username: from_secret: docker_username password: diff --git a/README.md b/README.md index e1e6e1fd..6c9ef63a 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ -# lemmy-ui - -The official web app for [Lemmy](https://github.com/LemmyNet/lemmy), written in inferno. - -Based off of MrFoxPro's [inferno-isomorphic-template](https://github.com/MrFoxPro/inferno-isomorphic-template). - -## Configuration - -The following environment variables can be used to configure lemmy-ui: - -`ENV_VAR` | type | default | description ---- | --- | --- | --- -`LEMMY_UI_HOST` | `string` | `0.0.0.0:1234` | The IP / port that the lemmy-ui isomorphic node server is hosted at. -`LEMMY_UI_LEMMY_INTERNAL_HOST` | `string` | `0.0.0.0:8536` | The internal IP / port that lemmy is hosted at. Often `lemmy:8536` if using docker. -`LEMMY_UI_LEMMY_EXTERNAL_HOST` | `string` | `0.0.0.0:8536` | The external IP / port that lemmy is hosted at. Often `DOMAIN.TLD`. -`LEMMY_UI_LEMMY_WS_HOST` | `string` | `0.0.0.0:8536` | An alternate location for lemmy's websocket address. Not usually necessary. -`LEMMY_UI_HTTPS` | `bool` | `false` | Whether to use https. -`LEMMY_UI_EXTRA_THEMES_FOLDER` | `string` | `./extra_themes` | A location for additional lemmy css themes. -`LEMMY_UI_DEBUG` | `bool` | `false` | Loads the [Eruda](https://github.com/liriliri/eruda) debugging utility. -`LEMMY_UI_DISABLE_CSP` | `bool` | `false` | Disables CSP security headers -`LEMMY_UI_CUSTOM_HTML_HEADER` | `string` | | Injects a custom script into ``. +# lemmy-ui + +The official web app for [Lemmy](https://github.com/LemmyNet/lemmy), written in inferno. + +Based off of MrFoxPro's [inferno-isomorphic-template](https://github.com/MrFoxPro/inferno-isomorphic-template). + +## Configuration + +The following environment variables can be used to configure lemmy-ui: + +| `ENV_VAR` | type | default | description | +| ------------------------------ | -------- | ---------------- | ----------------------------------------------------------------------------------- | +| `LEMMY_UI_HOST` | `string` | `0.0.0.0:1234` | The IP / port that the lemmy-ui isomorphic node server is hosted at. | +| `LEMMY_UI_LEMMY_INTERNAL_HOST` | `string` | `0.0.0.0:8536` | The internal IP / port that lemmy is hosted at. Often `lemmy:8536` if using docker. | +| `LEMMY_UI_LEMMY_EXTERNAL_HOST` | `string` | `0.0.0.0:8536` | The external IP / port that lemmy is hosted at. Often `DOMAIN.TLD`. | +| `LEMMY_UI_LEMMY_WS_HOST` | `string` | `0.0.0.0:8536` | An alternate location for lemmy's websocket address. Not usually necessary. | +| `LEMMY_UI_HTTPS` | `bool` | `false` | Whether to use https. | +| `LEMMY_UI_EXTRA_THEMES_FOLDER` | `string` | `./extra_themes` | A location for additional lemmy css themes. | +| `LEMMY_UI_DEBUG` | `bool` | `false` | Loads the [Eruda](https://github.com/liriliri/eruda) debugging utility. | +| `LEMMY_UI_DISABLE_CSP` | `bool` | `false` | Disables CSP security headers | +| `LEMMY_UI_CUSTOM_HTML_HEADER` | `string` | | Injects a custom script into ``. | diff --git a/package.json b/package.json index 2f16b8d3..62993df6 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build:prod": "webpack --mode=production", "clean": "yarn run rimraf dist", "dev": "yarn start", - "lint": "node generate_translations.js && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src && prettier --check \"src/**/*.{ts,tsx,js,css,scss}\"", + "lint": "node generate_translations.js && tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx \"src/**\" && prettier --check \"src/**/*.{ts,tsx,js,css,scss}\"", "prepare": "husky install", "start": "yarn build:dev --watch" }, @@ -89,6 +89,7 @@ "devDependencies": { "@babel/core": "^7.21.8", "@types/autosize": "^4.0.0", + "@types/bootstrap": "^5.2.6", "@types/express": "^4.17.17", "@types/html-to-text": "^9.0.0", "@types/markdown-it": "^12.2.3", diff --git a/src/assets/css/main.css b/src/assets/css/main.css index 9cff2c7f..a0d72394 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -1,7 +1,3 @@ -.navbar-toggler { - border: 0px; -} - .navbar-expand-lg .navbar-nav .nav-link { padding-right: 0.75rem !important; padding-left: 0.75rem !important; @@ -201,14 +197,6 @@ } } -.dropdown-content { - position: absolute; - background-color: var(--light); - min-width: 160px; - box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); - z-index: 2000; -} - blockquote { border-left: 2px solid var(--secondary); margin: 0.5em 5px; diff --git a/src/client/index.tsx b/src/client/index.tsx index d3a5b625..99f12371 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -3,6 +3,7 @@ import { BrowserRouter } from "inferno-router"; import { App } from "../shared/components/app/app"; import { initializeSite } from "../shared/utils"; +import "bootstrap/js/dist/collapse"; import "bootstrap/js/dist/dropdown"; const site = window.isoData.site_res; diff --git a/src/server/index.tsx b/src/server/index.tsx index 05988cf7..9d91f14d 100644 --- a/src/server/index.tsx +++ b/src/server/index.tsx @@ -356,7 +356,7 @@ export async function generateManifestBase64(site: Site) { async function fetchIconPng(iconUrl: string) { return await fetch( - iconUrl.replace(/https?:\/\/localhost:\d+/g, getHttpBaseInternal()) + iconUrl.replace(/https?:\/\/[^\/]+/g, getHttpBaseInternal()) ) .then(res => res.blob()) .then(blob => blob.arrayBuffer()); diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index 128d4023..f9497c7b 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -1,4 +1,4 @@ -import { Component, linkEvent } from "inferno"; +import { Component, createRef, linkEvent } from "inferno"; import { NavLink } from "inferno-router"; import { CommentResponse, @@ -39,14 +39,22 @@ interface NavbarProps { } interface NavbarState { - expanded: boolean; unreadInboxCount: number; unreadReportCount: number; unreadApplicationCount: number; - showDropdown: boolean; onSiteBanner?(url: string): any; } +function handleCollapseClick(i: Navbar) { + if (i.collapseButtonRef.current?.ariaExpanded === "true") { + i.collapseButtonRef.current?.click(); + } +} + +function handleLogOut() { + UserService.Instance.logout(); +} + export class Navbar extends Component { private wsSub: Subscription; private userSub: Subscription; @@ -57,10 +65,9 @@ export class Navbar extends Component { unreadInboxCount: 0, unreadReportCount: 0, unreadApplicationCount: 0, - expanded: false, - showDropdown: false, }; subscription: any; + collapseButtonRef = createRef(); constructor(props: any, context: any) { super(props, context); @@ -113,85 +120,228 @@ export class Navbar extends Component { this.unreadApplicationCountSub.unsubscribe(); } - render() { - return this.navbar(); - } - // TODO class active corresponding to current page - navbar() { - let siteView = this.props.siteRes.site_view; - let person = UserService.Instance.myUserInfo?.local_user_view.person; + render() { + const siteView = this.props.siteRes.site_view; + const person = UserService.Instance.myUserInfo?.local_user_view.person; return ( - ); @@ -464,23 +443,6 @@ export class Navbar extends Component { return amAdmin() || moderatesS; } - handleToggleExpandNavbar(i: Navbar) { - i.setState({ expanded: !i.state.expanded }); - } - - handleHideExpandNavbar(i: Navbar) { - i.setState({ expanded: false, showDropdown: false }); - } - - handleLogoutClick(i: Navbar) { - i.setState({ showDropdown: false, expanded: false }); - UserService.Instance.logout(); - } - - handleToggleDropdown(i: Navbar) { - i.setState({ showDropdown: !i.state.showDropdown }); - } - parseMessage(msg: any) { let op = wsUserOp(msg); console.log(msg); diff --git a/src/shared/components/comment/comment-node.tsx b/src/shared/components/comment/comment-node.tsx index 16e0a731..d2dee1e8 100644 --- a/src/shared/components/comment/comment-node.tsx +++ b/src/shared/components/comment/comment-node.tsx @@ -42,6 +42,7 @@ import { colorList, commentTreeMaxDepth, futureDaysToUnixTime, + getCommentParentId, isAdmin, isBanned, isMod, @@ -1051,11 +1052,14 @@ export class CommentNode extends Component { ? i18n.t("show_context") : i18n.t("link"); + // The context button should show the parent comment by default + const parentCommentId = getCommentParentId(cv.comment) ?? cv.comment.id; + return ( <> diff --git a/tsconfig.json b/tsconfig.json index d7c88030..3b7d3e41 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,28 @@ -{ - "compilerOptions": { - "pretty": true, - "target": "esnext", - "module": "esnext", - "allowSyntheticDefaultImports": true, - "preserveConstEnums": true, - "sourceMap": true, - "moduleResolution": "node", - "lib": ["es2017", "dom"], - "types": [ - "inferno" - ], - "jsx": "preserve", - "noUnusedLocals": true, - "baseUrl": "./src", - "noEmit": true, - "skipLibCheck": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "experimentalDecorators": true, - "strictNullChecks": true, - "noFallthroughCasesInSwitch": true - }, - "include": [ - "src/**/*", - "node_modules/inferno/dist/index.d.ts" - ] -} +{ + "compilerOptions": { + "pretty": true, + "target": "esnext", + "module": "esnext", + "allowSyntheticDefaultImports": true, + "preserveConstEnums": true, + "sourceMap": true, + "moduleResolution": "node", + "lib": ["es2017", "dom"], + "types": ["inferno"], + "jsx": "preserve", + "noUnusedLocals": true, + "baseUrl": "./src", + "noEmit": true, + "skipLibCheck": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "experimentalDecorators": true, + "strictNullChecks": true, + "noFallthroughCasesInSwitch": true + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx", + "node_modules/inferno/dist/index.d.ts" + ] +} diff --git a/yarn.lock b/yarn.lock index 24b8a351..9432cde1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1155,7 +1155,7 @@ picocolors "^1.0.0" tslib "^2.5.0" -"@popperjs/core@^2.9.0": +"@popperjs/core@^2.9.0", "@popperjs/core@^2.9.2": version "2.11.7" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== @@ -1235,6 +1235,13 @@ dependencies: "@types/node" "*" +"@types/bootstrap@^5.2.6": + version "5.2.6" + resolved "https://registry.yarnpkg.com/@types/bootstrap/-/bootstrap-5.2.6.tgz#e861b3aa1f4a1434da0bf50fbaa372b6f7e64d2f" + integrity sha512-BlAc3YATdasbHoxMoBWODrSF6qwQO/E9X8wVxCCSa6rWjnaZfpkr2N6pUMCY6jj2+wf0muUtLySbvU9etX6YqA== + dependencies: + "@popperjs/core" "^2.9.2" + "@types/connect-history-api-fallback@^1.3.5": version "1.5.0" resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz#9fd20b3974bdc2bcd4ac6567e2e0f6885cb2cf41"