Add unexposed account setting for hiding poll creation (#7972)

* Add unexposed account setting for hiding poll creation

This is to match the sticker picker setting we already have, but not exposed in the user settings until we decide if we actually want it to be there.

This is primarily intended to be used in environments that disable it at the config level, though given there's multiple people in the wild who have asked for this, it seems reasonable to expose it as a hidden setting instead. Note that as of writing it's not clear if any of those requests made it as far as an issue tracker.

Typically for the usecase presented we'd add a new UIFeature flag, however this *feels* wrong for the case at hand.

* Move visibility check way higher

* Fix i18n post-merge
pull/21833/head
Travis Ralston 2022-03-04 11:04:30 -07:00 committed by GitHub
parent aa48cfd0a0
commit b981a96b29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 4 deletions

View File

@ -87,6 +87,7 @@ interface IState {
isMenuOpen: boolean; isMenuOpen: boolean;
isStickerPickerOpen: boolean; isStickerPickerOpen: boolean;
showStickersButton: boolean; showStickersButton: boolean;
showPollsButton: boolean;
} }
@replaceableComponent("views.rooms.MessageComposer") @replaceableComponent("views.rooms.MessageComposer")
@ -117,11 +118,13 @@ export default class MessageComposer extends React.Component<IProps, IState> {
isMenuOpen: false, isMenuOpen: false,
isStickerPickerOpen: false, isStickerPickerOpen: false,
showStickersButton: SettingsStore.getValue("MessageComposerInput.showStickersButton"), showStickersButton: SettingsStore.getValue("MessageComposerInput.showStickersButton"),
showPollsButton: SettingsStore.getValue("MessageComposerInput.showPollsButton"),
}; };
this.instanceId = instanceCount++; this.instanceId = instanceCount++;
SettingsStore.monitorSetting("MessageComposerInput.showStickersButton", null); SettingsStore.monitorSetting("MessageComposerInput.showStickersButton", null);
SettingsStore.monitorSetting("MessageComposerInput.showPollsButton", null);
} }
private get voiceRecording(): Optional<VoiceRecording> { private get voiceRecording(): Optional<VoiceRecording> {
@ -189,6 +192,13 @@ export default class MessageComposer extends React.Component<IProps, IState> {
} }
break; break;
} }
case "MessageComposerInput.showPollsButton": {
const showPollsButton = SettingsStore.getValue("MessageComposerInput.showPollsButton");
if (this.state.showPollsButton !== showPollsButton) {
this.setState({ showPollsButton });
}
break;
}
} }
} }
} }
@ -459,6 +469,7 @@ export default class MessageComposer extends React.Component<IProps, IState> {
}} }}
setStickerPickerOpen={this.setStickerPickerOpen} setStickerPickerOpen={this.setStickerPickerOpen}
showLocationButton={!window.electron} showLocationButton={!window.electron}
showPollsButton={this.state.showPollsButton}
showStickersButton={this.state.showStickersButton} showStickersButton={this.state.showStickersButton}
toggleButtonMenu={this.toggleButtonMenu} toggleButtonMenu={this.toggleButtonMenu}
/> } /> }

View File

@ -48,6 +48,7 @@ interface IProps {
relation?: IEventRelation; relation?: IEventRelation;
setStickerPickerOpen: (isStickerPickerOpen: boolean) => void; setStickerPickerOpen: (isStickerPickerOpen: boolean) => void;
showLocationButton: boolean; showLocationButton: boolean;
showPollsButton: boolean;
showStickersButton: boolean; showStickersButton: boolean;
toggleButtonMenu: () => void; toggleButtonMenu: () => void;
} }
@ -73,7 +74,7 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
uploadButton(), // props passed via UploadButtonContext uploadButton(), // props passed via UploadButtonContext
showStickersButton(props), showStickersButton(props),
voiceRecordingButton(props, narrow), voiceRecordingButton(props, narrow),
pollButton(room, props.relation), props.showPollsButton && pollButton(room, props.relation),
showLocationButton(props, room, roomId, matrixClient), showLocationButton(props, room, roomId, matrixClient),
]; ];
} else { } else {
@ -84,7 +85,7 @@ const MessageComposerButtons: React.FC<IProps> = (props: IProps) => {
moreButtons = [ moreButtons = [
showStickersButton(props), showStickersButton(props),
voiceRecordingButton(props, narrow), voiceRecordingButton(props, narrow),
pollButton(room, props.relation), props.showPollsButton && pollButton(room, props.relation),
showLocationButton(props, room, roomId, matrixClient), showLocationButton(props, room, roomId, matrixClient),
]; ];
} }
@ -295,7 +296,7 @@ interface IPollButtonProps {
} }
class PollButton extends React.PureComponent<IPollButtonProps> { class PollButton extends React.PureComponent<IPollButtonProps> {
static contextType = OverflowMenuContext; public static contextType = OverflowMenuContext;
public context!: React.ContextType<typeof OverflowMenuContext>; public context!: React.ContextType<typeof OverflowMenuContext>;
private onCreateClick = () => { private onCreateClick = () => {
@ -336,7 +337,7 @@ class PollButton extends React.PureComponent<IPollButtonProps> {
} }
}; };
render() { public render() {
// do not allow sending polls within threads at this time // do not allow sending polls within threads at this time
if (this.props.relation?.rel_type === RelationType.Thread) return null; if (this.props.relation?.rel_type === RelationType.Thread) return null;

View File

@ -906,6 +906,7 @@
"Use custom size": "Use custom size", "Use custom size": "Use custom size",
"Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing", "Enable Emoji suggestions while typing": "Enable Emoji suggestions while typing",
"Show stickers button": "Show stickers button", "Show stickers button": "Show stickers button",
"Show polls button": "Show polls button",
"Insert a trailing colon after user mentions at the start of a message": "Insert a trailing colon after user mentions at the start of a message", "Insert a trailing colon after user mentions at the start of a message": "Insert a trailing colon after user mentions at the start of a message",
"Use a more compact 'Modern' layout": "Use a more compact 'Modern' layout", "Use a more compact 'Modern' layout": "Use a more compact 'Modern' layout",
"Show a placeholder for removed messages": "Show a placeholder for removed messages", "Show a placeholder for removed messages": "Show a placeholder for removed messages",

View File

@ -429,6 +429,11 @@ export const SETTINGS: {[setting: string]: ISetting} = {
default: true, default: true,
controller: new UIFeatureController(UIFeature.Widgets, false), controller: new UIFeatureController(UIFeature.Widgets, false),
}, },
"MessageComposerInput.showPollsButton": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Show polls button'),
default: true,
},
"MessageComposerInput.insertTrailingColon": { "MessageComposerInput.insertTrailingColon": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td('Insert a trailing colon after user mentions at the start of a message'), displayName: _td('Insert a trailing colon after user mentions at the start of a message'),

View File

@ -39,6 +39,7 @@ describe("MessageComposerButtons", () => {
<MessageComposerButtons <MessageComposerButtons
isMenuOpen={false} isMenuOpen={false}
showLocationButton={true} showLocationButton={true}
showPollsButton={true}
showStickersButton={true} showStickersButton={true}
toggleButtonMenu={() => {}} toggleButtonMenu={() => {}}
/>, />,
@ -57,6 +58,7 @@ describe("MessageComposerButtons", () => {
<MessageComposerButtons <MessageComposerButtons
isMenuOpen={true} isMenuOpen={true}
showLocationButton={true} showLocationButton={true}
showPollsButton={true}
showStickersButton={true} showStickersButton={true}
toggleButtonMenu={() => {}} toggleButtonMenu={() => {}}
/>, />,
@ -81,6 +83,7 @@ describe("MessageComposerButtons", () => {
<MessageComposerButtons <MessageComposerButtons
isMenuOpen={false} isMenuOpen={false}
showLocationButton={true} showLocationButton={true}
showPollsButton={true}
showStickersButton={true} showStickersButton={true}
toggleButtonMenu={() => {}} toggleButtonMenu={() => {}}
/>, />,
@ -98,6 +101,7 @@ describe("MessageComposerButtons", () => {
<MessageComposerButtons <MessageComposerButtons
isMenuOpen={true} isMenuOpen={true}
showLocationButton={true} showLocationButton={true}
showPollsButton={true}
showStickersButton={true} showStickersButton={true}
toggleButtonMenu={() => {}} toggleButtonMenu={() => {}}
/>, />,
@ -115,6 +119,56 @@ describe("MessageComposerButtons", () => {
], ],
]); ]);
}); });
describe('polls button', () => {
it('should render when asked to', () => {
const buttons = wrapAndRender(
<MessageComposerButtons
isMenuOpen={true}
showLocationButton={true}
showPollsButton={true}
showStickersButton={true}
toggleButtonMenu={() => {}}
/>,
true,
);
expect(buttonLabels(buttons)).toEqual([
"Emoji",
"More options",
[
"Attachment",
"Sticker",
"Poll",
"Location",
],
]);
});
it('should not render when asked not to', () => {
const buttons = wrapAndRender(
<MessageComposerButtons
isMenuOpen={true}
showLocationButton={true}
showPollsButton={false} // !! the change from the alternate test
showStickersButton={true}
toggleButtonMenu={() => {}}
/>,
true,
);
expect(buttonLabels(buttons)).toEqual([
"Emoji",
"More options",
[
"Attachment",
"Sticker",
// "Poll", // should be hidden
"Location",
],
]);
});
});
}); });
function wrapAndRender(component: React.ReactElement, narrow: boolean): ReactWrapper { function wrapAndRender(component: React.ReactElement, narrow: boolean): ReactWrapper {