Proof of concept for a flair tab in user settings

This commit is contained in:
Travis Ralston 2019-01-25 15:35:32 -07:00
parent 2061ce2dbf
commit 57e45e7e7c
7 changed files with 79 additions and 65 deletions

View file

@ -44,3 +44,8 @@ limitations under the License.
.mx_UserSettingsDialog_labsIcon:before {
mask-image: url('$(res)/img/feather-icons/flag.svg');
}
.mx_UserSettingsDialog_flairIcon:before {
// TODO: Use the real icon
mask-image: url('$(res)/img/feather-icons/flag.svg');
}

View file

@ -20,19 +20,8 @@ limitations under the License.
margin: 8px;
}
.mx_GroupPublicity_toggle > label {
display: flex;
align-items: flex-start;
}
.mx_GroupPublicity_toggle > label,
.mx_GroupPublicity_toggle .mx_GroupTile {
width: 50%;
}
.mx_GroupPublicity_toggle input {
margin-right: 8px;
vertical-align: -4px;
width: calc(100% - 60px); // 48px switch + some padding
}
.mx_GroupPublicity_toggle .mx_GroupTile {
@ -40,3 +29,7 @@ limitations under the License.
align-items: flex-start;
cursor: pointer;
}
.mx_GroupPublicity_toggle .mx_ToggleSwitch {
float: right;
}

View file

@ -28,6 +28,7 @@ import NotificationSettingsTab from "../settings/tabs/NotificationSettingsTab";
import PreferencesSettingsTab from "../settings/tabs/PreferencesSettingsTab";
import VoiceSettingsTab from "../settings/tabs/VoiceSettingsTab";
import HelpSettingsTab from "../settings/tabs/HelpSettingsTab";
import FlairSettingsTab from "../settings/tabs/FlairSettingsTab";
// TODO: Ditch this whole component
export class TempTab extends React.Component {
@ -58,6 +59,11 @@ export default class UserSettingsDialog extends React.Component {
"mx_UserSettingsDialog_settingsIcon",
<GeneralSettingsTab />,
));
tabs.push(new Tab(
_td("Flair"),
"mx_UserSettingsDialog_flairIcon",
<FlairSettingsTab />,
));
tabs.push(new Tab(
_td("Notifications"),
"mx_UserSettingsDialog_bellIcon",

View file

@ -18,7 +18,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import sdk from '../../../index';
import GroupStore from '../../../stores/GroupStore';
import { _t } from '../../../languageHandler.js';
import ToggleSwitch from "../elements/ToggleSwitch";
export default React.createClass({
displayName: 'GroupPublicityToggle',
@ -52,8 +52,7 @@ export default React.createClass({
if (this._groupStoreToken) this._groupStoreToken.unregister();
},
_onPublicityToggle: function(e) {
e.stopPropagation();
_onPublicityToggle: function() {
this.setState({
busy: true,
// Optimistic early update
@ -68,21 +67,11 @@ export default React.createClass({
render() {
const GroupTile = sdk.getComponent('groups.GroupTile');
const input = <input type="checkbox"
onChange={this._onPublicityToggle}
checked={this.state.isGroupPublicised}
/>;
const labelText = !this.state.ready ? _t("Loading...") :
(this.state.isGroupPublicised ?
_t("Flair will appear if enabled in room settings") :
_t("Flair will not appear")
);
return <div className="mx_GroupPublicity_toggle">
<GroupTile groupId={this.props.groupId} showDescription={false} avatarHeight={40} />
<label onClick={this._onPublicityToggle}>
{ input }
{ labelText }
</label>
<ToggleSwitch checked={this.state.isGroupPublicised}
disabled={!this.state.ready || this.state.busy}
onChange={this._onPublicityToggle} />
</div>;
},
});

View file

@ -43,9 +43,9 @@ export default React.createClass({
});
},
_renderGroupPublicity() {
render() {
let text = "";
let scrollbox = <div />;
let groupPublicityToggles = null;
const groups = this.state.groups;
if (this.state.error) {
@ -54,16 +54,10 @@ export default React.createClass({
text = _t('Loading...');
} else if (groups.length > 0) {
const GroupPublicityToggle = sdk.getComponent('groups.GroupPublicityToggle');
const GeminiScrollbarWrapper = sdk.getComponent('elements.GeminiScrollbarWrapper');
const groupPublicityToggles = groups.map((groupId, index) => {
groupPublicityToggles = groups.map((groupId, index) => {
return <GroupPublicityToggle key={index} groupId={groupId} />;
});
text = _t('Display your community flair in rooms configured to show it.');
scrollbox = <div className="mx_GroupUserSettings_groupPublicity_scrollbox">
<GeminiScrollbarWrapper>
{ groupPublicityToggles }
</GeminiScrollbarWrapper>
</div>;
} else {
text = _t("You're not currently a member of any communities.");
}
@ -71,16 +65,10 @@ export default React.createClass({
return (
<div>
<p className="mx_SettingsTab_subsectionText">{ text }</p>
{ scrollbox }
<div className='mx_SettingsTab_subsectionText'>
{ groupPublicityToggles }
</div>
</div>
);
},
render() {
const groupPublicity = this._renderGroupPublicity();
return <div>
{ groupPublicity }
</div>;
},
});

View file

@ -0,0 +1,52 @@
/*
Copyright 2019 New Vector Ltd
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 React from 'react';
import {_t} from "../../../../languageHandler";
import {DragDropContext} from "react-beautiful-dnd";
import GroupUserSettings from "../../groups/GroupUserSettings";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import PropTypes from "prop-types";
import {MatrixClient} from "matrix-js-sdk";
export default class FlairSettingsTab extends React.Component {
static childContextTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient),
};
constructor() {
super();
}
getChildContext() {
return {
matrixClient: MatrixClientPeg.get(),
};
}
render() {
return (
<div className="mx_SettingsTab">
<span className="mx_SettingsTab_heading">{_t("Flair")}</span>
<div className="mx_SettingsTab_section">
<DragDropContext>
<GroupUserSettings />
</DragDropContext>
</div>
</div>
);
}
}

View file

@ -16,11 +16,7 @@ limitations under the License.
import React from 'react';
import {_t} from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import GroupUserSettings from "../../groups/GroupUserSettings";
import PropTypes from "prop-types";
import {MatrixClient} from "matrix-js-sdk";
import { DragDropContext } from 'react-beautiful-dnd';
import ProfileSettings from "../ProfileSettings";
import EmailAddresses from "../EmailAddresses";
import PhoneNumbers from "../PhoneNumbers";
@ -37,10 +33,6 @@ const Modal = require("../../../../Modal");
const dis = require("../../../../dispatcher");
export default class GeneralSettingsTab extends React.Component {
static childContextTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient),
};
constructor() {
super();
@ -50,12 +42,6 @@ export default class GeneralSettingsTab extends React.Component {
};
}
getChildContext() {
return {
matrixClient: MatrixClientPeg.get(),
};
}
_onLanguageChange = (newLanguage) => {
if (this.state.language === newLanguage) return;
@ -110,11 +96,6 @@ export default class GeneralSettingsTab extends React.Component {
<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{_t("Profile")}</span>
<ProfileSettings />
<span className="mx_SettingsTab_subheading">{_t("Flair")}</span>
<DragDropContext>
<GroupUserSettings />
</DragDropContext>
</div>
);
}