Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesigned and improved the Notifications page #1548

Open
wants to merge 23 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c344dfb
Redesigned and improved Notification page
MMDJafari Aug 24, 2022
17f4624
Update notification-body.jsx
MMDJafari Aug 24, 2022
08b25e0
Redesigned and improved Notification page
MMDJafari Aug 24, 2022
5614b8c
fix mouse hover
MMDJafari Aug 25, 2022
4888fa0
fix mouse hover
MMDJafari Aug 25, 2022
b5bca32
Update notification-body.jsx
MMDJafari Aug 25, 2022
5b03bdf
fix user tag remover
MMDJafari Aug 25, 2022
8d28281
revert back to shows mentioned users in text and parse it with peaceo…
MMDJafari Aug 26, 2022
068b90e
yarn lint
MMDJafari Aug 26, 2022
66f14c5
remove clock icon
MMDJafari Aug 26, 2022
64241c5
improve spacing between lines
MMDJafari Aug 26, 2022
2c2a89c
fix showing text & profile picture for mobile devices
MMDJafari Aug 26, 2022
f3fe2de
improve spacing between lines
MMDJafari Aug 26, 2022
b5bf47e
fix url for vercel
MMDJafari Aug 27, 2022
c42ad5f
add IG reel preview
MMDJafari Aug 27, 2022
1a4e706
revert to default config
MMDJafari Aug 27, 2022
c846deb
Play video attachments using inline video tag - using @n1313 fork
MMDJafari Aug 31, 2022
3f136f5
Revert "Play video attachments using inline video tag - using @n1313 …
MMDJafari Aug 31, 2022
b7345fb
Play video attachments using inline video tag - using @n1313 fork
MMDJafari Aug 31, 2022
ab2fe3f
add .webm & .ogg to inline video player
MMDJafari Aug 31, 2022
9934fb5
stick navigation bar to the bottom of screen
MMDJafari Sep 5, 2022
162ceda
add dark subscription request alert style
MMDJafari Sep 5, 2022
f7ef932
rebase everything
MMDJafari Dec 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,42 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.110.0] - Not released
## [1.113] - Not released
### Added
- Email verification support. If verification is supported by server, the new
field (Verification code) is appear in Sign Up and Profile forms. When user
sets up or updates email address, they should receive verification code on it
and enter that code to the form.

## [1.112] - 2022-11-25
### Added
- Group administrators can now block users in their managed groups. A blocked
user cannot post to the group, but can read and comment if the group is not
private.
- Video attachments now have a player, when browser supports them
- YouTube shorts now supported in media viewer

### Fixed
- No refresh needed to view private users and groups after subscription approved
- No refresh needed to interact with new subscription requests
- Hidden comment class name updated to avoid interference with Firefox builtin extension style

## [1.111.2] - 2022-09-23
### Fixed
- Fix broken PhotoSwipe icons

## [1.111.1] - 2022-09-08
### Fixed
- Restore Vazir font (new css-loader didn't load it in 1.111.0)

## [1.111.0] - 2022-09-07
### Added
- Instagram Reels are supported by native previews.
First contribution by [Mohammad Jafari](https://github.com/MMDJafari/). Thanks!
- It is now possible to hide posts by hashtags! Also, the underlying algorithm
allows to add other types of hiding criteria in the future.

## [1.110.0] - 2022-06-29
### Fixed
- The erroneous "Remove from" items has been removed from the post's "More" menu
- Fixed domain-name in donate link
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2FFreeFeed%2Ffreefeed-react-client.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2FFreeFeed%2Ffreefeed-react-client?ref=badge_shield)

[Node.js](https://nodejs.org) 14 or 16 is supported.

We use [yarn](https://yarnpkg.com/) as dependency manager (instead of npm) so you need to install it and run `yarn` after downloading this code. If you're using Windows, you should install developer tools by using `npm install --global --production windows-build-tools` from an elevated PowerShell or CMD.exe (run as Administrator).

## Starting Development Server with Hot-Reload
Expand Down
2 changes: 1 addition & 1 deletion config/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default {
readMoreStyle: 'modern',
homeFeedSort: ACTIVITY,
homeFeedMode: HOMEFEED_MODE_CLASSIC,
homefeed: { hideUsers: [] },
homefeed: { hideUsers: [], hideTags: [] },
hidesInNonHomeFeeds: false,
pinnedGroups: [],
hideUnreadNotifications: false,
Expand Down
86 changes: 43 additions & 43 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reactive-pepyatka",
"version": "1.110.0",
"version": "1.113.0",
"description": "",
"main": "index.js",
"dependencies": {
Expand All @@ -9,9 +9,9 @@
"@fortawesome/free-solid-svg-icons": "~5.15.4",
"@sentry/react": "~6.19.7",
"autotrack": "~2.4.1",
"classnames": "~2.3.1",
"classnames": "~2.3.2",
"custom-event": "~1.0.1",
"date-fns": "~2.28.0",
"date-fns": "~2.29.3",
"debug": "~4.3.4",
"filesize": "~8.0.7",
"final-form": "~4.20.7",
Expand All @@ -20,7 +20,7 @@
"keycode-js": "~3.1.0",
"local-storage-fallback": "~4.1.2",
"lodash": "~4.17.21",
"lru-cache": "~7.10.2",
"lru-cache": "~7.14.1",
"memoize-one": "~6.0.0",
"mousetrap": "~1.6.5",
"porter-stemmer": "~0.9.1",
Expand All @@ -33,108 +33,108 @@
"react-helmet": "~6.1.0",
"react-photoswipe": "~1.3.0",
"react-portal": "~4.2.2",
"react-redux": "~7.2.8",
"react-redux": "~7.2.9",
"react-router": "~3.2.6",
"react-router-redux": "~4.0.8",
"react-select": "~1.2.1",
"react-sortablejs": "~2.0.11",
"react-textarea-autosize": "~8.3.4",
"recharts": "~2.1.12",
"recharts": "~2.1.16",
"redux": "~4.1.2",
"snarkdown": "~2.0.0",
"social-text-tokenizer": "~2.2.0",
"socket.io-client": "~2.3.1",
"tabbable": "~5.2.1",
"ua-parser-js": "~1.0.2",
"ua-parser-js": "~1.0.32",
"use-subscription": "~1.5.1",
"validator": "~13.7.0",
"vazir-font": "~30.1.0",
"whatwg-fetch": "~3.6.2"
},
"devDependencies": {
"@babel/core": "~7.18.6",
"@babel/eslint-parser": "~7.18.2",
"@babel/core": "~7.19.6",
"@babel/eslint-parser": "~7.19.1",
"@babel/plugin-proposal-class-properties": "~7.18.6",
"@babel/plugin-proposal-do-expressions": "~7.18.6",
"@babel/plugin-syntax-class-properties": "~7.12.13",
"@babel/plugin-transform-modules-commonjs": "~7.18.6",
"@babel/plugin-transform-react-constant-elements": "~7.18.6",
"@babel/plugin-transform-react-constant-elements": "~7.18.12",
"@babel/plugin-transform-react-inline-elements": "~7.18.6",
"@babel/plugin-transform-runtime": "~7.18.6",
"@babel/preset-env": "~7.18.6",
"@babel/plugin-transform-runtime": "~7.19.6",
"@babel/preset-env": "~7.19.4",
"@babel/preset-react": "~7.18.6",
"@babel/register": "~7.18.6",
"@babel/runtime": "~7.18.6",
"@babel/register": "~7.18.9",
"@babel/runtime": "~7.19.4",
"@gfx/zopfli": "~1.0.15",
"@testing-library/jest-dom": "~5.16.4",
"@testing-library/jest-dom": "~5.16.5",
"@testing-library/react": "~12.1.5",
"@testing-library/react-hooks": "~7.0.2",
"@testing-library/user-event": "~14.1.1",
"babel-eslint": "~10.1.0",
"babel-loader": "~8.2.5",
"babel-plugin-lodash": "~3.3.4",
"babel-plugin-transform-react-remove-prop-types": "~0.4.24",
"compression-webpack-plugin": "~9.2.0",
"copy-webpack-plugin": "~10.2.4",
"core-js": "~3.23.3",
"compression-webpack-plugin": "~10.0.0",
"copy-webpack-plugin": "~11.0.0",
"core-js": "~3.25.5",
"cross-env": "~7.0.3",
"css-loader": "~5.2.7",
"css-minimizer-webpack-plugin": "~3.4.1",
"eslint": "~8.18.0",
"css-loader": "~6.7.2",
"css-minimizer-webpack-plugin": "~4.0.0",
"eslint": "~8.23.1",
"eslint-config-prettier": "~8.5.0",
"eslint-plugin-babel": "~5.3.1",
"eslint-plugin-import": "~2.26.0",
"eslint-plugin-lodash": "~7.4.0",
"eslint-plugin-prettier": "~4.1.0",
"eslint-plugin-promise": "~6.0.0",
"eslint-plugin-react": "~7.30.1",
"eslint-plugin-prettier": "~4.2.1",
"eslint-plugin-promise": "~6.0.1",
"eslint-plugin-react": "~7.31.11",
"eslint-plugin-react-hooks": "~4.6.0",
"eslint-plugin-unicorn": "~42.0.0",
"eslint-plugin-unicorn": "~43.0.2",
"eslint-plugin-you-dont-need-lodash-underscore": "~6.12.0",
"eslint-webpack-plugin": "~3.2.0",
"file-loader": "~6.2.0",
"html-webpack-plugin": "~5.5.0",
"husky": "~8.0.1",
"husky": "~8.0.2",
"identity-obj-proxy": "~3.0.0",
"jest": "~27.5.1",
"jest-canvas-mock": "~2.3.1",
"jest-canvas-mock": "~2.4.0",
"lint-staged": "~12.4.3",
"mini-css-extract-plugin": "~2.6.1",
"mocha": "~9.2.2",
"mocha": "~10.0.0",
"mochapack": "~2.1.4",
"node-noop": "~1.0.0",
"node-sass": "~7.0.1",
"node-sass": "~7.0.3",
"npm-run-all": "~4.1.5",
"null-loader": "~4.0.1",
"prettier": "~2.7.1",
"pug": "~3.0.2",
"pug-loader": "~2.4.0",
"querystring": "~0.2.1",
"react-hot-loader": "~4.13.0",
"react-hot-loader": "~4.13.1",
"react-markdown-loader": "~1.3.1",
"react-test-renderer": "~17.0.2",
"regenerator-runtime": "~0.13.9",
"regenerator-runtime": "~0.13.11",
"resolve-url-loader": "~5.0.0",
"rimraf": "~3.0.2",
"sass-loader": "~12.6.0",
"sass-loader": "~13.0.2",
"sinon": "~13.0.2",
"style-loader": "~3.3.1",
"stylelint": "~14.9.1",
"stylelint-config-prettier": "~9.0.3",
"stylelint-config-standard-scss": "~3.0.0",
"stylelint": "~14.11.0",
"stylelint-config-prettier": "~9.0.4",
"stylelint-config-standard-scss": "~5.0.0",
"stylelint-prettier": "~2.0.0",
"stylelint-scss": "~4.2.0",
"terser-webpack-plugin": "~5.3.3",
"unexpected": "~12.0.4",
"stylelint-scss": "~4.3.0",
"terser-webpack-plugin": "~5.3.6",
"unexpected": "~13.0.1",
"unexpected-react": "~6.0.2",
"unexpected-sinon": "~11.1.0",
"url": "~0.11.0",
"webpack": "~5.73.0",
"webpack-bundle-analyzer": "~4.5.0",
"webpack": "~5.74.0",
"webpack-bundle-analyzer": "~4.6.1",
"webpack-cli": "~4.10.0",
"webpack-dev-server": "~4.9.2",
"webpack-dev-server": "~4.11.1",
"webpack-node-externals": "~3.0.0",
"webpack-version-file": "~0.1.6",
"webpack-version-file": "~0.1.7",
"worker-loader": "~3.0.8"
},
"resolutions": {
Expand Down Expand Up @@ -167,5 +167,5 @@
"url": "https://github.com/FreeFeed/freefeed-react-client.git"
},
"license": "MIT",
"packageManager": "yarn@3.2.1"
"packageManager": "yarn@3.3.0"
}
2 changes: 1 addition & 1 deletion src/components/app-updated.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function AppUpdated() {
return (
<div className={styles.bar}>
<div className={styles.indicator}>
There’s a new update for {CONFIG.siteTitle} available!{' '}
There’s an update for {CONFIG.siteTitle}!{' '}
<ButtonLink className={styles.refresh} onClick={reloadPage}>
Refresh the page
</ButtonLink>{' '}
Expand Down
42 changes: 42 additions & 0 deletions src/components/block-in-group-form.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { blockUserInGroup } from '../redux/action-creators';

export function BlockInGroupForm({ groupName }) {
const dispatch = useDispatch();
const status = useSelector((state) => state.blockUserInGroupStatus);

const [text, setText] = useState('');
const canSubmit = !!text.trim() && !status.loading;
const onInput = useCallback((e) => setText(e.target.value), []);
const onSubmit = useCallback(
(e) => (e.preventDefault(), dispatch(blockUserInGroup(groupName, text.trim()))),
[dispatch, groupName, text],
);

useEffect(() => status.success && setText(''), [status.success]);

return (
<form onSubmit={onSubmit}>
<p className="input-group" style={{ maxWidth: '24em' }}>
<input
className="form-control"
type="text"
placeholder="username to block"
value={text}
onInput={onInput}
/>
<span className="input-group-btn">
<button className="btn btn-default" type="submit" disabled={!canSubmit}>
Block!
</button>
</span>
</p>
{status.error && (
<p className="alert alert-danger" role="alert">
{status.errorText}
</p>
)}
</form>
);
}
70 changes: 70 additions & 0 deletions src/components/email-verification-subform.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { sendVerificationCode } from '../redux/action-creators';
import { groupErrClass } from './form-utils';
import { useServerInfo } from './hooks/server-info';

export function EmailVerificationSubform({ emailField, codeField, create = false }) {
const dispatch = useDispatch();
const sendStatus = useSelector((state) => state.sendVerificationCodeStatus);
const [serverInfo, serverInfoStatus] = useServerInfo();

const verificationEnabled = serverInfoStatus.success && serverInfo.emailVerificationEnabled;

const shouldVerify = Boolean(
verificationEnabled && emailField.meta.dirty && !emailField.meta.invalid,
);

const [lastSentTo, setLastSentTo] = useState('');

const sendEmailCode = useCallback(() => {
dispatch(sendVerificationCode(emailField.input.value, create ? 'sign-up' : 'update'));
setLastSentTo(emailField.input.value);
}, [create, dispatch, emailField.input.value]);

return (
shouldVerify && (
<div className="alert alert-warning wider-input">
<label htmlFor="emailCode-input">Email verification</label>
<p className="help-block">
To confirm {create ? 'your' : 'updated'} email address, please click{' '}
<button
className="btn btn-default"
type="button"
onClick={sendEmailCode}
disabled={sendStatus.loading}
>
Send Code
</button>{' '}
and enter the code that we will send to <strong>{emailField.input.value}</strong>.
</p>
{sendStatus.loading && (
<p className="text-info">
Sending code to <strong>{lastSentTo}</strong>...
</p>
)}
{sendStatus.success && (
<p className="text-success">
Code was sent to <strong>{lastSentTo}</strong>, please check your mailbox (and,
probably, the Spam folder)
</p>
)}
{sendStatus.error && (
<p className="text-danger">
Error sending to <strong>{lastSentTo}</strong>: {sendStatus.errorText}
</p>
)}
<p className={groupErrClass(codeField, true)}>
<input
id="emailCode-input"
className="form-control narrow-input"
type="text"
autoComplete="off"
placeholder="Code from email"
{...codeField.input}
/>
</p>
</div>
)
);
}
9 changes: 6 additions & 3 deletions src/components/feed.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class Feed extends PureComponent {
}
}

const postIsHidden = (post) => !!(post.isHidden || post.hiddenByNames);
const postIsHidden = (post) => !!(post.isHidden || post.hiddenByCriteria);

export default connect(
(state) => {
Expand Down Expand Up @@ -151,14 +151,17 @@ function FeedEntry({ post, section, ...props }) {
const onPostUnmount = useCallback((offset) => setHideLinkTopOffset(offset), []);

const isRecentlyHidden =
props.separateHiddenEntries && (post.isHidden || post.hiddenByNames) && section === 'visible';
props.separateHiddenEntries &&
(post.isHidden || post.hiddenByCriteria) &&
section === 'visible';

return isRecentlyHidden ? (
<PostRecentlyHidden
id={post.id}
initialTopOffset={hideLinkTopOffset}
isHidden={post.isHidden}
recipientNames={post.recipientNames}
availableHideCriteria={post.availableHideCriteria}
hiddenByCriteria={post.hiddenByCriteria}
/>
) : (
<Post
Expand Down
Loading