mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 02:05:45 +03:00
Fix: Avatar preview does not update when same file is selected repeatedly (#8288)
* Fix: Avatar preview does not update when same file is selected repeatedly Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
7600182a35
commit
dbcb56f75e
9 changed files with 48 additions and 3 deletions
|
@ -30,6 +30,7 @@ import Modal from "../../../../Modal";
|
|||
import InteractiveAuthDialog from "../InteractiveAuthDialog";
|
||||
import DialogButtons from "../../elements/DialogButtons";
|
||||
import BaseDialog from "../BaseDialog";
|
||||
import { chromeFileInputFix } from "../../../../utils/BrowserWorkarounds";
|
||||
|
||||
// Maximum acceptable size of a key file. It's 59 characters including the spaces we encode,
|
||||
// so this should be plenty and allow for people putting extra whitespace in the file because
|
||||
|
@ -403,6 +404,7 @@ export default class AccessSecretStorageDialog extends React.PureComponent<IProp
|
|||
<input type="file"
|
||||
className="mx_AccessSecretStorageDialog_recoveryKeyEntry_fileInput"
|
||||
ref={this.fileUpload}
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={this.onRecoveryKeyFileChange}
|
||||
/>
|
||||
<AccessibleButton kind="primary" onClick={this.onRecoveryKeyFileUploadClick}>
|
||||
|
|
|
@ -25,6 +25,7 @@ import { useTimeout } from "../../../hooks/useTimeout";
|
|||
import Analytics from "../../../Analytics";
|
||||
import { TranslatedString } from '../../../languageHandler';
|
||||
import RoomContext from "../../../contexts/RoomContext";
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
export const AVATAR_SIZE = 52;
|
||||
|
||||
|
@ -62,6 +63,7 @@ const MiniAvatarUploader: React.FC<IProps> = ({ hasAvatar, hasAvatarLabel, noAva
|
|||
type="file"
|
||||
ref={uploadRef}
|
||||
className="mx_MiniAvatarUploader_input"
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={async (ev) => {
|
||||
if (!ev.target.files?.length) return;
|
||||
setBusy(true);
|
||||
|
|
|
@ -22,6 +22,7 @@ import Field from "../elements/Field";
|
|||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import AvatarSetting from "../settings/AvatarSetting";
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
|
@ -252,6 +253,7 @@ export default class RoomProfileSettings extends React.Component<IProps, IState>
|
|||
type="file"
|
||||
ref={this.avatarUpload}
|
||||
className="mx_ProfileSettings_avatarUpload"
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={this.onAvatarChanged}
|
||||
accept="image/*"
|
||||
/>
|
||||
|
|
|
@ -37,6 +37,7 @@ import ContentMessages from '../../../ContentMessages';
|
|||
import MatrixClientContext from '../../../contexts/MatrixClientContext';
|
||||
import RoomContext from '../../../contexts/RoomContext';
|
||||
import { useDispatcher } from "../../../hooks/useDispatcher";
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
interface IProps {
|
||||
addEmoji: (emoji: string) => boolean;
|
||||
|
@ -236,6 +237,7 @@ const UploadButtonContextProvider: React.FC<IUploadButtonProps> = ({ roomId, rel
|
|||
type="file"
|
||||
style={uploadInputStyle}
|
||||
multiple
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={onUploadFileInputChange}
|
||||
/>
|
||||
</UploadButtonContext.Provider>;
|
||||
|
|
|
@ -26,6 +26,7 @@ import Spinner from '../elements/Spinner';
|
|||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
import RoomAvatar from '../avatars/RoomAvatar';
|
||||
import BaseAvatar from '../avatars/BaseAvatar';
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
interface IProps {
|
||||
initialAvatarUrl?: string;
|
||||
|
@ -182,7 +183,7 @@ export default class ChangeAvatar extends React.Component<IProps, IState> {
|
|||
uploadSection = (
|
||||
<div className={this.props.className}>
|
||||
{ _t("Upload new:") }
|
||||
<input type="file" accept="image/*" onChange={this.onFileSelected} />
|
||||
<input type="file" accept="image/*" onClick={chromeFileInputFix} onChange={this.onFileSelected} />
|
||||
{ this.state.errorText }
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -29,6 +29,7 @@ import AccessibleButton from '../elements/AccessibleButton';
|
|||
import AvatarSetting from './AvatarSetting';
|
||||
import ExternalLink from '../elements/ExternalLink';
|
||||
import UserIdentifierCustomisations from '../../../customisations/UserIdentifier';
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
interface IState {
|
||||
userId?: string;
|
||||
|
@ -188,6 +189,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
|
|||
type="file"
|
||||
ref={this.avatarUpload}
|
||||
className="mx_ProfileSettings_avatarUpload"
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={this.onAvatarChanged}
|
||||
accept="image/*"
|
||||
/>
|
||||
|
|
|
@ -31,6 +31,7 @@ import { RoomNotifState } from '../../../../../RoomNotifs';
|
|||
import defaultDispatcher from "../../../../../dispatcher/dispatcher";
|
||||
import { Action } from "../../../../../dispatcher/actions";
|
||||
import { UserTab } from "../../../dialogs/UserTab";
|
||||
import { chromeFileInputFix } from "../../../../../utils/BrowserWorkarounds";
|
||||
|
||||
interface IProps {
|
||||
roomId: string;
|
||||
|
@ -77,7 +78,7 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
|
|||
this.soundUpload.current.click();
|
||||
};
|
||||
|
||||
private onSoundUploadChanged = (e: React.ChangeEvent<HTMLInputElement>): Promise<void> => {
|
||||
private onSoundUploadChanged = (e: React.ChangeEvent<HTMLInputElement>): void => {
|
||||
if (!e.target.files || !e.target.files.length) {
|
||||
this.setState({
|
||||
uploadedFile: null,
|
||||
|
@ -254,7 +255,14 @@ export default class NotificationsSettingsTab extends React.Component<IProps, IS
|
|||
<h3>{ _t("Set a new custom sound") }</h3>
|
||||
<div className="mx_SettingsFlag">
|
||||
<form autoComplete="off" noValidate={true}>
|
||||
<input ref={this.soundUpload} className="mx_NotificationSound_soundUpload" type="file" onChange={this.onSoundUploadChanged} accept="audio/*" />
|
||||
<input
|
||||
ref={this.soundUpload}
|
||||
className="mx_NotificationSound_soundUpload"
|
||||
type="file"
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={this.onSoundUploadChanged}
|
||||
accept="audio/*"
|
||||
/>
|
||||
</form>
|
||||
|
||||
{ currentUploadedFile }
|
||||
|
|
|
@ -19,6 +19,7 @@ import React, { useRef, useState } from "react";
|
|||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import Field from "../elements/Field";
|
||||
import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
||||
|
||||
interface IProps {
|
||||
avatarUrl?: string;
|
||||
|
@ -89,6 +90,7 @@ export const SpaceAvatar = ({
|
|||
<input
|
||||
type="file"
|
||||
ref={avatarUploadRef}
|
||||
onClick={chromeFileInputFix}
|
||||
onChange={(e) => {
|
||||
if (!e.target.files?.length) return;
|
||||
const file = e.target.files[0];
|
||||
|
|
24
src/utils/BrowserWorkarounds.ts
Normal file
24
src/utils/BrowserWorkarounds.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { MouseEvent } from "react";
|
||||
|
||||
export function chromeFileInputFix(event: MouseEvent<HTMLInputElement>): void {
|
||||
// Workaround for Chromium Bug
|
||||
// Chrome does not fire onChange events if the same file is selected twice
|
||||
// Only required on Chromium-based browsers (Electron, Chrome, Edge, Opera, Vivaldi, etc)
|
||||
event.currentTarget.value = '';
|
||||
}
|
Loading…
Reference in a new issue