PLT-3114 Moved preview collapse out of pre-release features (#3206)
* Added user setting to auto collapse image previews * Added slash commands for collapsing/expanding image previews * Added translation strings for collapse setting * Add default props for preview collapse setting
Этот коммит содержится в:
коммит произвёл
Corey Hulen
родитель
629b49a119
Коммит
1e245f19c7
77
api/command_expand_collapse.go
Обычный файл
77
api/command_expand_collapse.go
Обычный файл
@@ -0,0 +1,77 @@
|
|||||||
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/platform/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ExpandProvider struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type CollapseProvider struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
CMD_EXPAND = "expand"
|
||||||
|
CMD_COLLAPSE = "collapse"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RegisterCommandProvider(&ExpandProvider{})
|
||||||
|
RegisterCommandProvider(&CollapseProvider{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *ExpandProvider) GetTrigger() string {
|
||||||
|
return CMD_EXPAND
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *CollapseProvider) GetTrigger() string {
|
||||||
|
return CMD_COLLAPSE
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *ExpandProvider) GetCommand(c *Context) *model.Command {
|
||||||
|
return &model.Command{
|
||||||
|
Trigger: CMD_EXPAND,
|
||||||
|
AutoComplete: true,
|
||||||
|
AutoCompleteDesc: c.T("api.command_expand.desc"),
|
||||||
|
DisplayName: c.T("api.command_expand.name"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *CollapseProvider) GetCommand(c *Context) *model.Command {
|
||||||
|
return &model.Command{
|
||||||
|
Trigger: CMD_COLLAPSE,
|
||||||
|
AutoComplete: true,
|
||||||
|
AutoCompleteDesc: c.T("api.command_collapse.desc"),
|
||||||
|
DisplayName: c.T("api.command_collapse.name"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *ExpandProvider) DoCommand(c *Context, channelId string, message string) *model.CommandResponse {
|
||||||
|
return setCollapsePreference(c, "false")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *CollapseProvider) DoCommand(c *Context, channelId string, message string) *model.CommandResponse {
|
||||||
|
return setCollapsePreference(c, "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCollapsePreference(c *Context, value string) *model.CommandResponse {
|
||||||
|
pref := model.Preference{
|
||||||
|
UserId: c.Session.UserId,
|
||||||
|
Category: model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS,
|
||||||
|
Name: model.PREFERENCE_NAME_COLLAPSE_SETTING,
|
||||||
|
Value: value,
|
||||||
|
}
|
||||||
|
|
||||||
|
if result := <-Srv.Store.Preference().Save(&model.Preferences{pref}); result.Err != nil {
|
||||||
|
return &model.CommandResponse{Text: c.T("api.command_expand_collapse.fail.app_error"), ResponseType: model.COMMAND_RESPONSE_TYPE_EPHEMERAL}
|
||||||
|
}
|
||||||
|
|
||||||
|
socketMessage := model.NewMessage("", "", c.Session.UserId, model.ACTION_PREFERENCE_CHANGED)
|
||||||
|
socketMessage.Add("preference", pref.ToJson())
|
||||||
|
go Publish(socketMessage)
|
||||||
|
|
||||||
|
return &model.CommandResponse{}
|
||||||
|
}
|
||||||
47
api/command_expand_collapse_test.go
Обычный файл
47
api/command_expand_collapse_test.go
Обычный файл
@@ -0,0 +1,47 @@
|
|||||||
|
// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See License.txt for license information.
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/mattermost/platform/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestExpandCommand(t *testing.T) {
|
||||||
|
th := Setup().InitBasic()
|
||||||
|
Client := th.BasicClient
|
||||||
|
channel := th.BasicChannel
|
||||||
|
|
||||||
|
r1 := Client.Must(Client.Command(channel.Id, "/expand", false)).Data.(*model.CommandResponse)
|
||||||
|
if r1 == nil {
|
||||||
|
t.Fatal("Command failed to execute")
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
p1 := Client.Must(Client.GetPreference(model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSE_SETTING)).Data.(*model.Preference)
|
||||||
|
if p1.Value != "false" {
|
||||||
|
t.Fatal("preference not updated correctly")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCollapseCommand(t *testing.T) {
|
||||||
|
th := Setup().InitBasic()
|
||||||
|
Client := th.BasicClient
|
||||||
|
channel := th.BasicChannel
|
||||||
|
|
||||||
|
r1 := Client.Must(Client.Command(channel.Id, "/collapse", false)).Data.(*model.CommandResponse)
|
||||||
|
if r1 == nil {
|
||||||
|
t.Fatal("Command failed to execute")
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
|
p1 := Client.Must(Client.GetPreference(model.PREFERENCE_CATEGORY_DISPLAY_SETTINGS, model.PREFERENCE_NAME_COLLAPSE_SETTING)).Data.(*model.Preference)
|
||||||
|
if p1.Value != "true" {
|
||||||
|
t.Fatal("preference not updated correctly")
|
||||||
|
}
|
||||||
|
}
|
||||||
20
i18n/en.json
20
i18n/en.json
@@ -399,6 +399,26 @@
|
|||||||
"id": "api.command_echo.name",
|
"id": "api.command_echo.name",
|
||||||
"translation": "echo"
|
"translation": "echo"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "api.command_collapse.desc",
|
||||||
|
"translation": "Turn on auto-collapsing of image previews"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.command_collapse.name",
|
||||||
|
"translation": "collapse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.command_expand.desc",
|
||||||
|
"translation": "Turn off auto-collapsing of image previews"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.command_expand_collapse.fail.app_error",
|
||||||
|
"translation": "An error occured while expanding previews"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "api.command_expand.name",
|
||||||
|
"translation": "expand"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "api.command_join.desc",
|
"id": "api.command_join.desc",
|
||||||
"translation": "Join the open channel"
|
"translation": "Join the open channel"
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ const (
|
|||||||
PREFERENCE_CATEGORY_TUTORIAL_STEPS = "tutorial_step"
|
PREFERENCE_CATEGORY_TUTORIAL_STEPS = "tutorial_step"
|
||||||
PREFERENCE_CATEGORY_ADVANCED_SETTINGS = "advanced_settings"
|
PREFERENCE_CATEGORY_ADVANCED_SETTINGS = "advanced_settings"
|
||||||
|
|
||||||
|
PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings"
|
||||||
|
PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews"
|
||||||
|
|
||||||
PREFERENCE_CATEGORY_LAST = "last"
|
PREFERENCE_CATEGORY_LAST = "last"
|
||||||
PREFERENCE_NAME_LAST_CHANNEL = "channel"
|
PREFERENCE_NAME_LAST_CHANNEL = "channel"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ export default class Post extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextProps.previewCollapsed !== this.props.previewCollapsed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Utils.areObjectsEqual(nextProps.user, this.props.user)) {
|
if (!Utils.areObjectsEqual(nextProps.user, this.props.user)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -190,6 +194,7 @@ export default class Post extends React.Component {
|
|||||||
parentPost={parentPost}
|
parentPost={parentPost}
|
||||||
handleCommentClick={this.handleCommentClick}
|
handleCommentClick={this.handleCommentClick}
|
||||||
compactDisplay={this.props.compactDisplay}
|
compactDisplay={this.props.compactDisplay}
|
||||||
|
previewCollapsed={this.props.previewCollapsed}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -213,5 +218,6 @@ Post.propTypes = {
|
|||||||
currentUser: React.PropTypes.object.isRequired,
|
currentUser: React.PropTypes.object.isRequired,
|
||||||
center: React.PropTypes.bool,
|
center: React.PropTypes.bool,
|
||||||
compactDisplay: React.PropTypes.bool,
|
compactDisplay: React.PropTypes.bool,
|
||||||
|
previewCollapsed: React.PropTypes.string,
|
||||||
commentCount: React.PropTypes.number
|
commentCount: React.PropTypes.number
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,7 +25,11 @@ export default class PostBody extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Utils.areObjectsEqual(nextProps.compactDisplay, this.props.compactDisplay)) {
|
if (nextProps.compactDisplay !== this.props.compactDisplay) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nextProps.previewCollapsed !== this.props.previewCollapsed) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +176,7 @@ export default class PostBody extends React.Component {
|
|||||||
post={this.props.post}
|
post={this.props.post}
|
||||||
message={messageWrapper}
|
message={messageWrapper}
|
||||||
compactDisplay={this.props.compactDisplay}
|
compactDisplay={this.props.compactDisplay}
|
||||||
|
previewCollapsed={this.props.previewCollapsed}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -193,5 +198,6 @@ PostBody.propTypes = {
|
|||||||
parentPost: React.PropTypes.object,
|
parentPost: React.PropTypes.object,
|
||||||
retryPost: React.PropTypes.func.isRequired,
|
retryPost: React.PropTypes.func.isRequired,
|
||||||
handleCommentClick: React.PropTypes.func.isRequired,
|
handleCommentClick: React.PropTypes.func.isRequired,
|
||||||
compactDisplay: React.PropTypes.bool
|
compactDisplay: React.PropTypes.bool,
|
||||||
|
previewCollapsed: React.PropTypes.string
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,10 +22,14 @@ export default class PostBodyAdditionalContent extends React.Component {
|
|||||||
this.toggleEmbedVisibility = this.toggleEmbedVisibility.bind(this);
|
this.toggleEmbedVisibility = this.toggleEmbedVisibility.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
embedVisible: true
|
embedVisible: props.previewCollapsed.startsWith('false')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
this.setState({embedVisible: nextProps.previewCollapsed.startsWith('false')});
|
||||||
|
}
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) {
|
if (!Utils.areObjectsEqual(nextProps.post, this.props.post)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -118,7 +122,7 @@ export default class PostBodyAdditionalContent extends React.Component {
|
|||||||
|
|
||||||
if (generateEmbed) {
|
if (generateEmbed) {
|
||||||
let messageWithToggle = [];
|
let messageWithToggle = [];
|
||||||
if (Utils.isFeatureEnabled(Constants.PRE_RELEASE_FEATURES.EMBED_TOGGLE)) {
|
|
||||||
// if message has only one line and starts with a link place toggle in this only line
|
// if message has only one line and starts with a link place toggle in this only line
|
||||||
// else - place it in new line between message and embed
|
// else - place it in new line between message and embed
|
||||||
const prependToggle = (/^\s*https?:\/\/.*$/).test(this.props.post.message);
|
const prependToggle = (/^\s*https?:\/\/.*$/).test(this.props.post.message);
|
||||||
@@ -130,14 +134,12 @@ export default class PostBodyAdditionalContent extends React.Component {
|
|||||||
onClick={this.toggleEmbedVisibility}
|
onClick={this.toggleEmbedVisibility}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (prependToggle) {
|
if (prependToggle) {
|
||||||
messageWithToggle.push(this.props.message);
|
messageWithToggle.push(this.props.message);
|
||||||
} else {
|
} else {
|
||||||
messageWithToggle.unshift(this.props.message);
|
messageWithToggle.unshift(this.props.message);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
messageWithToggle.push(this.props.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -156,8 +158,12 @@ export default class PostBodyAdditionalContent extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PostBodyAdditionalContent.defaultProps = {
|
||||||
|
previewCollapsed: 'false'
|
||||||
|
};
|
||||||
PostBodyAdditionalContent.propTypes = {
|
PostBodyAdditionalContent.propTypes = {
|
||||||
post: React.PropTypes.object.isRequired,
|
post: React.PropTypes.object.isRequired,
|
||||||
|
message: React.PropTypes.element.isRequired,
|
||||||
compactDisplay: React.PropTypes.bool,
|
compactDisplay: React.PropTypes.bool,
|
||||||
message: React.PropTypes.element.isRequired
|
previewCollapsed: React.PropTypes.string
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -260,6 +260,7 @@ export default class PostList extends React.Component {
|
|||||||
center={this.props.displayPostsInCenter}
|
center={this.props.displayPostsInCenter}
|
||||||
commentCount={commentCount}
|
commentCount={commentCount}
|
||||||
compactDisplay={this.props.compactDisplay}
|
compactDisplay={this.props.compactDisplay}
|
||||||
|
previewCollapsed={this.props.previewsCollapsed}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -520,5 +521,6 @@ PostList.propTypes = {
|
|||||||
postsToHighlight: React.PropTypes.object,
|
postsToHighlight: React.PropTypes.object,
|
||||||
displayNameType: React.PropTypes.string,
|
displayNameType: React.PropTypes.string,
|
||||||
displayPostsInCenter: React.PropTypes.bool,
|
displayPostsInCenter: React.PropTypes.bool,
|
||||||
compactDisplay: React.PropTypes.bool
|
compactDisplay: React.PropTypes.bool,
|
||||||
|
previewsCollapsed: React.PropTypes.string
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ export default class PostViewController extends React.Component {
|
|||||||
scrollType: ScrollTypes.NEW_MESSAGE,
|
scrollType: ScrollTypes.NEW_MESSAGE,
|
||||||
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
||||||
displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
||||||
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT
|
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT,
|
||||||
|
previewsCollapsed: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, 'false')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,11 +68,19 @@ export default class PostViewController extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onPreferenceChange() {
|
onPreferenceChange(category) {
|
||||||
|
// Bit of a hack to force render when this setting is updated
|
||||||
|
// regardless of change
|
||||||
|
let previewSuffix = '';
|
||||||
|
if (category === Preferences.CATEGORY_DISPLAY_SETTINGS) {
|
||||||
|
previewSuffix = '_' + Utils.generateId();
|
||||||
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
||||||
displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
||||||
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT
|
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT,
|
||||||
|
previewsCollapsed: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, 'false') + previewSuffix
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +141,7 @@ export default class PostViewController extends React.Component {
|
|||||||
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
displayNameType: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'false'),
|
||||||
displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
displayPostsInCenter: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT) === Preferences.CHANNEL_DISPLAY_MODE_CENTERED,
|
||||||
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT,
|
compactDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT) === Preferences.MESSAGE_DISPLAY_COMPACT,
|
||||||
|
previewsCollapsed: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, 'false'),
|
||||||
scrollType: ScrollTypes.NEW_MESSAGE
|
scrollType: ScrollTypes.NEW_MESSAGE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -183,6 +193,10 @@ export default class PostViewController extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (nextState.previewsCollapsed !== this.state.previewsCollapsed) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (nextState.lastViewed !== this.state.lastViewed) {
|
if (nextState.lastViewed !== this.state.lastViewed) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -241,6 +255,7 @@ export default class PostViewController extends React.Component {
|
|||||||
displayNameType={this.state.displayNameType}
|
displayNameType={this.state.displayNameType}
|
||||||
displayPostsInCenter={this.state.displayPostsInCenter}
|
displayPostsInCenter={this.state.displayPostsInCenter}
|
||||||
compactDisplay={this.state.compactDisplay}
|
compactDisplay={this.state.compactDisplay}
|
||||||
|
previewsCollapsed={this.state.previewsCollapsed}
|
||||||
lastViewed={this.state.lastViewed}
|
lastViewed={this.state.lastViewed}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -234,13 +234,6 @@ export default class AdvancedSettingsDisplay extends React.Component {
|
|||||||
defaultMessage='Show preview snippet of links below message'
|
defaultMessage='Show preview snippet of links below message'
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'EMBED_TOGGLE':
|
|
||||||
return (
|
|
||||||
<FormattedMessage
|
|
||||||
id='user.settings.advance.embed_toggle'
|
|
||||||
defaultMessage='Show toggle for all embed previews'
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ function getDisplayStateFromStores() {
|
|||||||
nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'),
|
nameFormat: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'name_format', 'username'),
|
||||||
selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT),
|
selectedFont: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, 'selected_font', Constants.DEFAULT_FONT),
|
||||||
channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT),
|
channelDisplayMode: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.CHANNEL_DISPLAY_MODE, Preferences.CHANNEL_DISPLAY_MODE_DEFAULT),
|
||||||
messageDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT)
|
messageDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.MESSAGE_DISPLAY, Preferences.MESSAGE_DISPLAY_DEFAULT),
|
||||||
|
collapseDisplay: PreferenceStore.get(Preferences.CATEGORY_DISPLAY_SETTINGS, Preferences.COLLAPSE_DISPLAY, Preferences.COLLAPSE_DISPLAY_DEFAULT)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +42,11 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
this.updateSection = this.updateSection.bind(this);
|
this.updateSection = this.updateSection.bind(this);
|
||||||
this.updateState = this.updateState.bind(this);
|
this.updateState = this.updateState.bind(this);
|
||||||
this.deactivate = this.deactivate.bind(this);
|
this.deactivate = this.deactivate.bind(this);
|
||||||
|
this.createCollapseSection = this.createCollapseSection.bind(this);
|
||||||
|
|
||||||
this.state = getDisplayStateFromStores();
|
this.state = getDisplayStateFromStores();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
const userId = UserStore.getCurrentId();
|
const userId = UserStore.getCurrentId();
|
||||||
|
|
||||||
@@ -77,8 +80,14 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
name: Preferences.MESSAGE_DISPLAY,
|
name: Preferences.MESSAGE_DISPLAY,
|
||||||
value: this.state.messageDisplay
|
value: this.state.messageDisplay
|
||||||
};
|
};
|
||||||
|
const collapseDisplayPreference = {
|
||||||
|
user_id: userId,
|
||||||
|
category: Preferences.CATEGORY_DISPLAY_SETTINGS,
|
||||||
|
name: Preferences.COLLAPSE_DISPLAY,
|
||||||
|
value: this.state.collapseDisplay
|
||||||
|
};
|
||||||
|
|
||||||
AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference],
|
AsyncClient.savePreferences([timePreference, namePreference, fontPreference, channelDisplayModePreference, messageDisplayPreference, collapseDisplayPreference],
|
||||||
() => {
|
() => {
|
||||||
this.updateSection('');
|
this.updateSection('');
|
||||||
},
|
},
|
||||||
@@ -87,27 +96,38 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClockRadio(militaryTime) {
|
handleClockRadio(militaryTime) {
|
||||||
this.setState({militaryTime});
|
this.setState({militaryTime});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNameRadio(nameFormat) {
|
handleNameRadio(nameFormat) {
|
||||||
this.setState({nameFormat});
|
this.setState({nameFormat});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleChannelDisplayModeRadio(channelDisplayMode) {
|
handleChannelDisplayModeRadio(channelDisplayMode) {
|
||||||
this.setState({channelDisplayMode});
|
this.setState({channelDisplayMode});
|
||||||
}
|
}
|
||||||
|
|
||||||
handlemessageDisplayRadio(messageDisplay) {
|
handlemessageDisplayRadio(messageDisplay) {
|
||||||
this.setState({messageDisplay});
|
this.setState({messageDisplay});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFont(selectedFont) {
|
handleFont(selectedFont) {
|
||||||
Utils.applyFont(selectedFont);
|
Utils.applyFont(selectedFont);
|
||||||
this.setState({selectedFont});
|
this.setState({selectedFont});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleCollapseRadio(collapseDisplay) {
|
||||||
|
this.setState({collapseDisplay});
|
||||||
|
}
|
||||||
|
|
||||||
updateSection(section) {
|
updateSection(section) {
|
||||||
$('.settings-modal .modal-body').scrollTop(0).perfectScrollbar('update');
|
$('.settings-modal .modal-body').scrollTop(0).perfectScrollbar('update');
|
||||||
this.updateState();
|
this.updateState();
|
||||||
this.props.updateSection(section);
|
this.props.updateSection(section);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateState() {
|
updateState() {
|
||||||
const newState = getDisplayStateFromStores();
|
const newState = getDisplayStateFromStores();
|
||||||
if (!Utils.areObjectsEqual(newState, this.state)) {
|
if (!Utils.areObjectsEqual(newState, this.state)) {
|
||||||
@@ -115,9 +135,118 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deactivate() {
|
deactivate() {
|
||||||
this.updateState();
|
this.updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createCollapseSection() {
|
||||||
|
if (this.props.activeSection === 'collapse') {
|
||||||
|
const collapseFormat = [false, false];
|
||||||
|
if (this.state.collapseDisplay === 'true') {
|
||||||
|
collapseFormat[0] = true;
|
||||||
|
} else {
|
||||||
|
collapseFormat[1] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUpdateCollapseSection = (e) => {
|
||||||
|
this.updateSection('');
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
const inputs = [
|
||||||
|
<div key='userDisplayCollapseOptions'>
|
||||||
|
<div className='radio'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
name='collapseFormat'
|
||||||
|
checked={collapseFormat[0]}
|
||||||
|
onChange={this.handleCollapseRadio.bind(this, 'true')}
|
||||||
|
/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseOn'
|
||||||
|
defaultMessage='On'
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div className='radio'>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
type='radio'
|
||||||
|
name='collapseFormat'
|
||||||
|
checked={collapseFormat[1]}
|
||||||
|
onChange={this.handleCollapseRadio.bind(this, 'false')}
|
||||||
|
/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseOff'
|
||||||
|
defaultMessage='Off'
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<br/>
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseDesc'
|
||||||
|
defaultMessage='Toggle whether to automatically collapse all image previews.'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SettingItemMax
|
||||||
|
title={
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseDisplay'
|
||||||
|
defaultMessage='Auto Collapse Previews'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
inputs={inputs}
|
||||||
|
submit={this.handleSubmit}
|
||||||
|
server_error={this.state.serverError}
|
||||||
|
updateSection={handleUpdateCollapseSection}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let describe;
|
||||||
|
if (this.state.collapseDisplay === 'true') {
|
||||||
|
describe = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseOn'
|
||||||
|
defaultMessage='On'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
describe = (
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseOff'
|
||||||
|
defaultMessage='Off'
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleUpdateCollapseSection = () => {
|
||||||
|
this.props.updateSection('collapse');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SettingItemMin
|
||||||
|
title={
|
||||||
|
<FormattedMessage
|
||||||
|
id='user.settings.display.collapseDisplay'
|
||||||
|
defaultMessage='Auto Collapse Previews'
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
describe={describe}
|
||||||
|
updateSection={handleUpdateCollapseSection}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const serverError = this.state.serverError || null;
|
const serverError = this.state.serverError || null;
|
||||||
let clockSection;
|
let clockSection;
|
||||||
@@ -127,6 +256,8 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
let languagesSection;
|
let languagesSection;
|
||||||
let messageDisplaySection;
|
let messageDisplaySection;
|
||||||
|
|
||||||
|
const collapseSection = this.createCollapseSection();
|
||||||
|
|
||||||
if (this.props.activeSection === 'clock') {
|
if (this.props.activeSection === 'clock') {
|
||||||
const clockFormat = [false, false];
|
const clockFormat = [false, false];
|
||||||
if (this.state.militaryTime === 'true') {
|
if (this.state.militaryTime === 'true') {
|
||||||
@@ -729,6 +860,8 @@ export default class UserSettingsDisplay extends React.Component {
|
|||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
{nameFormatSection}
|
{nameFormatSection}
|
||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
|
{collapseSection}
|
||||||
|
<div className='divider-dark'/>
|
||||||
{messageDisplaySection}
|
{messageDisplaySection}
|
||||||
<div className='divider-dark'/>
|
<div className='divider-dark'/>
|
||||||
{channelDisplayModeSection}
|
{channelDisplayModeSection}
|
||||||
|
|||||||
@@ -1290,6 +1290,10 @@
|
|||||||
"user.settings.developer.register": "Register New Application",
|
"user.settings.developer.register": "Register New Application",
|
||||||
"user.settings.developer.thirdParty": "Open to register a new third-party application",
|
"user.settings.developer.thirdParty": "Open to register a new third-party application",
|
||||||
"user.settings.developer.title": "Developer Settings",
|
"user.settings.developer.title": "Developer Settings",
|
||||||
|
"user.settings.display.collapseOn": "On",
|
||||||
|
"user.settings.display.collapseOff": "Off",
|
||||||
|
"user.settings.display.collapseDesc": "Toggle whether to automatically collapse all image previews.",
|
||||||
|
"user.settings.display.collapseDisplay": "Auto Collapse Previews",
|
||||||
"user.settings.display.channelDisplayTitle": "Channel Display Mode",
|
"user.settings.display.channelDisplayTitle": "Channel Display Mode",
|
||||||
"user.settings.display.channeldisplaymode": "Select the width of the center channel.",
|
"user.settings.display.channeldisplaymode": "Select the width of the center channel.",
|
||||||
"user.settings.display.clockDisplay": "Clock Display",
|
"user.settings.display.clockDisplay": "Clock Display",
|
||||||
|
|||||||
@@ -82,8 +82,8 @@ class PreferenceStoreClass extends EventEmitter {
|
|||||||
this.preferences.clear();
|
this.preferences.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
emitChange() {
|
emitChange(category) {
|
||||||
this.emit(CHANGE_EVENT);
|
this.emit(CHANGE_EVENT, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
addChangeListener(callback) {
|
addChangeListener(callback) {
|
||||||
@@ -101,7 +101,7 @@ class PreferenceStoreClass extends EventEmitter {
|
|||||||
case ActionTypes.RECEIVED_PREFERENCE: {
|
case ActionTypes.RECEIVED_PREFERENCE: {
|
||||||
const preference = action.preference;
|
const preference = action.preference;
|
||||||
this.setPreference(preference.category, preference.name, preference.value);
|
this.setPreference(preference.category, preference.name, preference.value);
|
||||||
this.emitChange();
|
this.emitChange(preference.category);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ActionTypes.RECEIVED_PREFERENCES:
|
case ActionTypes.RECEIVED_PREFERENCES:
|
||||||
|
|||||||
@@ -547,7 +547,9 @@ export default {
|
|||||||
MESSAGE_DISPLAY: 'message_display',
|
MESSAGE_DISPLAY: 'message_display',
|
||||||
MESSAGE_DISPLAY_CLEAN: 'clean',
|
MESSAGE_DISPLAY_CLEAN: 'clean',
|
||||||
MESSAGE_DISPLAY_COMPACT: 'compact',
|
MESSAGE_DISPLAY_COMPACT: 'compact',
|
||||||
MESSAGE_DISPLAY_DEFAULT: 'clean'
|
MESSAGE_DISPLAY_DEFAULT: 'clean',
|
||||||
|
COLLAPSE_DISPLAY: 'collapse_previews',
|
||||||
|
COLLAPSE_DISPLAY_DEFAULT: 'false'
|
||||||
},
|
},
|
||||||
TutorialSteps: {
|
TutorialSteps: {
|
||||||
INTRO_SCREENS: 0,
|
INTRO_SCREENS: 0,
|
||||||
@@ -728,10 +730,6 @@ export default {
|
|||||||
EMBED_PREVIEW: {
|
EMBED_PREVIEW: {
|
||||||
label: 'embed_preview',
|
label: 'embed_preview',
|
||||||
description: 'Show preview snippet of links below message'
|
description: 'Show preview snippet of links below message'
|
||||||
},
|
|
||||||
EMBED_TOGGLE: {
|
|
||||||
label: 'embed_toggle',
|
|
||||||
description: 'Show toggle for all embed previews'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
OVERLAY_TIME_DELAY: 400,
|
OVERLAY_TIME_DELAY: 400,
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user