Skip to content

Commit

Permalink
Merge branch 'release' into beta
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmz committed Oct 8, 2024
2 parents e33d74e + 5be9cff commit b72d2f4
Show file tree
Hide file tree
Showing 12 changed files with 2,688 additions and 3,422 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
!/.yarn/sdks
!/.yarn/versions
/_dist/
/dev-dist/
/config.json
/coverage
/node_modules
Expand Down
894 changes: 0 additions & 894 deletions .yarn/releases/yarn-4.3.1.cjs

This file was deleted.

925 changes: 925 additions & 0 deletions .yarn/releases/yarn-4.5.0.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.3.1.cjs
yarnPath: .yarn/releases/yarn-4.5.0.cjs
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ 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).

## Experimental

## [1.135.0] - 2024-10-08
### Added
- The PWA manifest and the service worker was added. The service worker caches
all site assets, including web fonts. It also caches user profile pictures (up
to 100 entries). The AppUpdated component periodically checks the service
worker for update.
### Changed
- Enable player for video attachments. Add a playback time limit for it.
### Fixed
- The SmartTextarea component now handles the 'onPaste' event more precisely.
When the clipboard contains the text and the image in the same time, both are
pasted.
- The recipients list of a post was determined incorrectly if some of the post
groups were not on the page.

## [1.134.4] - 2024-08-26
### Changed
Expand Down
68 changes: 34 additions & 34 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
"autotrack": "~2.4.1",
"classnames": "~2.5.1",
"custom-event": "~1.0.1",
"date-fns": "~3.6.0",
"debug": "~4.3.6",
"date-fns": "~4.1.0",
"debug": "~4.3.7",
"events": "~3.3.0",
"filesize": "~10.1.4",
"filesize": "~10.1.6",
"final-form": "~4.20.10",
"focus-trap-react": "~10.2.3",
"focus-visible": "~5.2.0",
"iso-639-1": "~3.1.2",
"focus-trap-react": "~10.3.0",
"focus-visible": "~5.2.1",
"iso-639-1": "~3.1.3",
"keycode-js": "~3.1.0",
"local-storage-fallback": "~4.1.2",
"lodash-es": "~4.17.21",
"lru-cache": "~10.3.1",
"lru-cache": "~11.0.1",
"memoize-one": "~6.0.0",
"mousetrap": "~1.6.5",
"photoswipe": "~5.4.4",
Expand All @@ -37,7 +37,7 @@
"react-redux": "~9.1.2",
"react-router": "~3.2.6",
"react-router-redux": "~4.0.8",
"react-select": "~5.8.0",
"react-select": "~5.8.1",
"react-sortablejs": "~6.1.4",
"react-textarea-autosize": "~8.5.3",
"react-use-event-hook": "~0.9.6",
Expand All @@ -46,68 +46,68 @@
"snarkdown": "~2.0.0",
"social-text-tokenizer": "~3.0.0",
"socket.io-client": "~2.3.1",
"sortablejs": "~1.15.2",
"sortablejs": "~1.15.3",
"tabbable": "~6.2.0",
"ua-parser-js": "~1.0.38",
"ua-parser-js": "~1.0.39",
"use-subscription": "~1.8.2",
"validator": "~13.12.0",
"vazirmatn": "^33.0.3",
"whatwg-fetch": "~3.6.20"
},
"devDependencies": {
"@babel/core": "~7.24.9",
"@babel/eslint-parser": "~7.25.1",
"@babel/preset-react": "~7.24.7",
"@babel/core": "~7.25.7",
"@babel/eslint-parser": "~7.25.7",
"@babel/preset-react": "~7.25.7",
"@gfx/zopfli": "~1.0.15",
"@testing-library/dom": "~10.4.0",
"@testing-library/jest-dom": "~6.4.8",
"@testing-library/react": "~16.0.0",
"@testing-library/jest-dom": "~6.5.0",
"@testing-library/react": "~16.0.1",
"@testing-library/react-hooks": "~8.0.1",
"@testing-library/user-event": "~14.5.2",
"@vitejs/plugin-legacy": "~5.4.1",
"@vitejs/plugin-react-swc": "^3.7.0",
"@vitejs/plugin-legacy": "~5.4.2",
"@vitejs/plugin-react-swc": "^3.7.1",
"cross-env": "~7.0.3",
"esbuild": "~0.23.0",
"esbuild": "~0.24.0",
"eslint": "~8.56.0",
"eslint-config-prettier": "~9.1.0",
"eslint-plugin-babel": "~5.3.1",
"eslint-plugin-import": "~2.29.1",
"eslint-plugin-import": "~2.31.0",
"eslint-plugin-lodash": "~8.0.0",
"eslint-plugin-prettier": "~5.2.1",
"eslint-plugin-promise": "~6.4.0",
"eslint-plugin-react": "~7.35.0",
"eslint-plugin-promise": "~7.1.0",
"eslint-plugin-react": "~7.37.1",
"eslint-plugin-react-hooks": "~4.6.2",
"eslint-plugin-unicorn": "~54.0.0",
"eslint-plugin-unicorn": "~56.0.0",
"eslint-plugin-you-dont-need-lodash-underscore": "~6.14.0",
"glob": "~11.0.0",
"gray-matter": "~4.0.3",
"husky": "~8.0.3",
"jsdom": "~24.1.1",
"lint-staged": "~15.2.7",
"jsdom": "~25.0.1",
"lint-staged": "~15.2.10",
"node-html-parser": "~6.1.13",
"npm-run-all": "~4.1.5",
"prettier": "~3.3.3",
"querystring": "~0.2.1",
"react-test-renderer": "~18.3.1",
"remarkable": "~2.0.1",
"rimraf": "~5.0.9",
"sass": "^1.77.8",
"sinon": "~18.0.0",
"stylelint": "~16.7.0",
"rimraf": "~6.0.1",
"sass": "^1.79.4",
"sinon": "~19.0.2",
"stylelint": "~16.9.0",
"stylelint-config-prettier": "~9.0.5",
"stylelint-config-standard-scss": "~13.1.0",
"stylelint-prettier": "~5.0.2",
"stylelint-scss": "~6.4.1",
"terser": "~5.31.3",
"stylelint-scss": "~6.7.0",
"terser": "~5.34.1",
"unexpected": "~13.2.1",
"unexpected-react": "~6.0.2",
"unexpected-sinon": "~11.1.0",
"url": "~0.11.4",
"vite": "~5.3.5",
"vite": "~5.4.8",
"vite-plugin-compression": "~0.5.1",
"vite-plugin-generate-file": "~0.2.0",
"vite-plugin-pwa": "^0.20.1",
"vitest": "~2.0.4",
"vite-plugin-pwa": "^0.20.5",
"vitest": "~2.1.2",
"workbox-window": "^7.1.0"
},
"scripts": {
Expand All @@ -130,5 +130,5 @@
"url": "https://github.com/FreeFeed/freefeed-react-client.git"
},
"license": "MIT",
"packageManager": "yarn@4.3.1"
"packageManager": "yarn@4.5.0"
}
2 changes: 1 addition & 1 deletion src/components/footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function Footer({ short }) {
return (
<footer className="footer">
<p role="navigation">
&copy; FreeFeed 1.134.4-beta (Sep 3, 2024)
&copy; FreeFeed 1.135.0-beta (Oct 8, 2024)
<br />
<Link to="/about">About</Link>
{' | '}
Expand Down
127 changes: 76 additions & 51 deletions src/components/post/post-attachment-video.jsx
Original file line number Diff line number Diff line change
@@ -1,67 +1,92 @@
import { PureComponent } from 'react';
import { useEffect, useRef, useState } from 'react';
import { faFileVideo, faPlayCircle } from '@fortawesome/free-regular-svg-icons';
import { faTimes } from '@fortawesome/free-solid-svg-icons';

import { useEvent } from 'react-use-event-hook';
import { formatFileSize } from '../../utils';
import { ButtonLink } from '../button-link';
import { Icon } from '../fontawesome-icons';

class VideoAttachment extends PureComponent {
state = {
isOpen: false,
};
export default function VideoAttachment({
id,
url,
fileName,
fileSize,
removeAttachment,
isEditing,
}) {
const [isOpen, setIsOpen] = useState(false);

handleClickOnRemoveAttachment = () => {
this.props.removeAttachment(this.props.id);
};
const handleClickOnRemoveAttachment = useEvent(() => removeAttachment(id));
const toggleOpen = useEvent(() => setIsOpen(true));

toggleOpen = () => {
this.setState({ isOpen: true });
};
const formattedFileSize = formatFileSize(fileSize);
const title = `${fileName} (${formattedFileSize})`;

render() {
const { props } = this;
const { isOpen } = this.state;
const formattedFileSize = formatFileSize(props.fileSize);
const videoRef = useRef(null);

const title = `${props.fileName} (${formattedFileSize})`;
// Prevent video from playing infinitely (we has this situation once and don't
// want it to happen again)
useEffect(() => {
if (!isOpen || !videoRef.current) {
return;
}
const videoEl = videoRef.current;

return (
<div className="attachment" role="figure" aria-label={`Video attachment ${title}`}>
{isOpen ? (
<div>
<video title={title} autoPlay controls>
<source src={props.url} />
Your browser does not support HTML5 video tag.
</video>
</div>
) : (
<ButtonLink
onClick={this.toggleOpen}
className="video-attachment-click-to-play"
title="Click to play video"
>
<Icon icon={faPlayCircle} />
</ButtonLink>
)}
<div>
<a href={props.url} title={title} target="_blank">
<Icon icon={faFileVideo} className="attachment-icon" />
<span>{title}</span>
</a>
// By default, the video playback should be paused after 5 minutes
let maxPlayTime = 300 * 1000;
let playTimer = 0;
const onPlay = () => {
clearTimeout(playTimer);
playTimer = setTimeout(() => videoEl.pause(), maxPlayTime);
};
const onPause = () => clearTimeout(playTimer);
const onDurationChange = () => {
// Video in playback mode should not be longer than 10 times of the video duration
maxPlayTime = videoEl.duration * 10 * 1000;
};
const { signal, abort } = new AbortController();

{props.isEditing && (
<Icon
icon={faTimes}
className="remove-attachment"
title="Remove video file"
onClick={this.handleClickOnRemoveAttachment}
/>
)}
videoEl.addEventListener('durationchange', onDurationChange, { once: true, signal });
videoEl.addEventListener('play', onPlay, { signal });
videoEl.addEventListener('pause', onPause, { signal });
signal.addEventListener('abort', onPause);
return () => abort();
}, [isOpen]);

return (
<div className="attachment" role="figure" aria-label={`Video attachment ${title}`}>
{isOpen ? (
<div>
<video title={title} autoPlay controls ref={videoRef}>
<source src={url} />
Your browser does not support HTML5 video tag.
</video>
</div>
) : (
<ButtonLink
onClick={toggleOpen}
className="video-attachment-click-to-play"
title="Click to play video"
>
<Icon icon={faPlayCircle} />
</ButtonLink>
)}
<div>
<a href={url} title={title} target="_blank">
<Icon icon={faFileVideo} className="attachment-icon" />
<span>{title}</span>
</a>

{isEditing && (
<Icon
icon={faTimes}
className="remove-attachment"
title="Remove video file"
onClick={handleClickOnRemoveAttachment}
/>
)}
</div>
);
}
</div>
);
}

export default VideoAttachment;
15 changes: 3 additions & 12 deletions src/components/post/post-attachments.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import AudioAttachment from './post-attachment-audio';
import GeneralAttachment from './post-attachment-general';
import VideoAttachment from './post-attachment-video';

/*
const videoTypes = {
mov: 'video/quicktime',
mp4: 'video/mp4; codecs="avc1.42E01E"',
Expand All @@ -16,19 +15,11 @@ const videoTypes = {

// find video-types which browser supports
let video = document.createElement('video');
const supportedVideoTypes = [];
Object.keys(videoTypes).forEach((extension) => {
const mime = videoTypes[extension];
const supportedVideoTypes = Object.entries(videoTypes)
.filter(([, mime]) => video.canPlayType(mime) === 'probably')
.map(([extension]) => extension);

if (video.canPlayType(mime) !== '') {
supportedVideoTypes.push(extension);
}
});
video = null;
*/

// No video support for now
const supportedVideoTypes = [];

const looksLikeAVideoFile = (attachment) => {
const lowercaseFileName = attachment.fileName.toLowerCase();
Expand Down
2 changes: 1 addition & 1 deletion src/components/select-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export const joinPostData = (state) => (postId) => {
const isDirectToSelf = userId === post.createdBy && subscriptionType === 'Directs';
return !isDirectToSelf ? userId : false;
})
.map((userId) => state.subscribers[userId])
.map((userId) => state.subscribers[userId] || state.users[userId])
.filter((user) => user);

// All recipient names and the post's author name.
Expand Down
8 changes: 0 additions & 8 deletions src/components/smart-textarea.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,6 @@ function useFile(onFile, ref) {

const items = [...e.clipboardData.items];

// If there is some plain text in clipboard, use it and don't try to find image
if (items.some((it) => it.type.startsWith('text/plain'))) {
return;
}

const imagePromises = [];
for (const it of items) {
if (!it.type.startsWith('image/')) {
Expand All @@ -208,9 +203,6 @@ function useFile(onFile, ref) {
imagePromises.push(Promise.resolve(blob));
}
}
if (imagePromises.length > 0) {
e.preventDefault();
}

// Call 'onFile' in order of imagePromises
imagePromises.reduce(async (prev, it) => {
Expand Down
Loading

0 comments on commit b72d2f4

Please sign in to comment.