This commit is contained in:
Diego Mello 2017-11-20 15:27:37 +00:00 committed by GitHub
commit d5a667b710
11 changed files with 180 additions and 16 deletions

View File

@ -27,6 +27,7 @@ export const FORGOT_PASSWORD = createRequestTypes('FORGOT_PASSWORD', [
'INIT'
]);
export const ROOMS = createRequestTypes('ROOMS');
export const ROOM_ROLES = createRequestTypes('ROOM_ROLES');
export const APP = createRequestTypes('APP', ['READY', 'INIT']);
export const MESSAGES = createRequestTypes('MESSAGES', [
...defaultTypes,

View File

@ -25,6 +25,12 @@ export function setAllSettings(settings) {
payload: settings
};
}
export function setAllPermissions(permissions) {
return {
type: types.SET_ALL_PERMISSIONS,
payload: permissions
};
}
export function login() {
return {
type: 'LOGIN'

20
app/actions/roomRoles.js Normal file
View File

@ -0,0 +1,20 @@
import * as types from './actionsTypes';
export function roomRolesRequest() {
return {
type: types.ROOM_ROLES.REQUEST
};
}
export function roomRolesSuccess(roles) {
return {
type: types.ROOM_ROLES.SUCCESS,
roles
};
}
export function roomRolesFailure() {
return {
type: types.ROOM_ROLES.FAILURE
};
}

View File

@ -1,2 +1,3 @@
export const SET_CURRENT_SERVER = 'SET_CURRENT_SERVER';
export const SET_ALL_SETTINGS = 'SET_ALL_SETTINGS';
export const SET_ALL_PERMISSIONS = 'SET_ALL_PERMISSIONS';

View File

@ -5,6 +5,7 @@ import { emojify } from 'react-emojione';
import Markdown from 'react-native-easy-markdown'; // eslint-disable-line
import ActionSheet from 'react-native-actionsheet';
import { connect } from 'react-redux';
import * as moment from 'moment';
import Card from './Card';
import User from './User';
@ -19,11 +20,6 @@ import {
} from '../../actions/messages';
import RocketChat from '../../lib/rocketchat';
const title = 'Message actions';
const options = ['Cancel', 'Reply', 'Edit', 'Permalink', 'Copy', 'Quote', 'Star Message', 'Pin Message', 'Delete'];
const CANCEL_INDEX = 0;
const DESTRUCTIVE_INDEX = 8;
const styles = StyleSheet.create({
content: {
flexGrow: 1,
@ -48,7 +44,10 @@ const styles = StyleSheet.create({
@connect(state => ({
message: state.messages.message,
permalink: state.messages.permalink,
user: state.login.user
user: state.login.user,
permissions: state.permissions,
Message_AllowEditing: state.settings.Message_AllowEditing,
Message_AllowEditing_BlockEditInMinutes: state.settings.Message_AllowEditing_BlockEditInMinutes
}), dispatch => ({
deleteRequest: message => dispatch(deleteRequest(message)),
editInit: message => dispatch(editInit(message)),
@ -69,6 +68,9 @@ export default class Message extends React.Component {
togglePinRequest: PropTypes.func.isRequired,
setInput: PropTypes.func.isRequired,
user: PropTypes.object.isRequired,
permissions: PropTypes.object.isRequired,
Message_AllowEditing: PropTypes.bool,
Message_AllowEditing_BlockEditInMinutes: PropTypes.number,
message: PropTypes.object,
permalink: PropTypes.string
}
@ -82,6 +84,16 @@ export default class Message extends React.Component {
};
this.handleActionPress = this.handleActionPress.bind(this);
this.showActions = this.showActions.bind(this);
// this.options = ['Cancel', 'Reply', 'Edit', 'Permalink', 'Copy', 'Quote', 'Star Message', 'Pin Message', 'Delete'];
this.CANCEL_INDEX = 0;
this.options = ['Cancel'];
this.options.push('Reply');
if (this.allowEdit()) {
this.addButton('Edit');
}
this.options.push('Delete');
this.DESTRUCTIVE_INDEX = this.options.length - 1;
}
async componentWillReceiveProps(nextProps) {
@ -113,6 +125,32 @@ export default class Message extends React.Component {
}
}
addButton = () => {
this.options.push('Edit');
}
allowEdit = () => {
const hasPermission = this.props.permissions['edit-message'];
const isEditAllowed = this.props.Message_AllowEditing;
const editOwn = this.props.item.u && this.props.item.u._id === this.props.user.id;
if (!(hasPermission || (isEditAllowed && editOwn))) {
return false;
}
const blockEditInMinutes = this.props.Message_AllowEditing_BlockEditInMinutes;
if (blockEditInMinutes) {
let msgTs;
if (this.props.item.ts != null) {
msgTs = moment(this.props.item.ts);
}
let currentTsDiff;
if (msgTs != null) {
currentTsDiff = moment().diff(msgTs, 'minutes');
}
return currentTsDiff < blockEditInMinutes;
}
return true;
}
isDeleted() {
return !this.props.item.msg;
}
@ -206,9 +244,6 @@ export default class Message extends React.Component {
// delete
} else if (actionIndex === 8) {
this.handleDelete();
// reply
} else {
console.log(actionIndex, this.props.item);
}
}
@ -262,10 +297,10 @@ export default class Message extends React.Component {
</View>
<ActionSheet
ref={o => this.ActionSheet = o}
title={title}
options={options}
cancelButtonIndex={CANCEL_INDEX}
destructiveButtonIndex={DESTRUCTIVE_INDEX}
title='Messages actions'
options={this.options}
cancelButtonIndex={this.CANCEL_INDEX}
destructiveButtonIndex={this.DESTRUCTIVE_INDEX}
onPress={this.handleActionPress}
/>
</View>

View File

@ -22,6 +22,23 @@ const settingsSchema = {
}
};
const permissionsRolesSchema = {
name: 'permissionsRoles',
properties: {
value: 'string'
}
};
const permissionsSchema = {
name: 'permissions',
primaryKey: '_id',
properties: {
_id: 'string',
_server: 'servers',
roles: { type: 'list', objectType: 'permissionsRoles' }
}
};
const roomsSchema = {
name: 'rooms',
primaryKey: '_id',
@ -128,7 +145,9 @@ const realm = new Realm({
usersSchema,
roomsSchema,
attachment,
messagesEditedBySchema
messagesEditedBySchema,
permissionsSchema,
permissionsRolesSchema
]
});
export default realm;

View File

@ -83,6 +83,29 @@ const RocketChat = {
reduxStore.dispatch(actions.setAllSettings(settings));
});
Meteor.call('permissions/get', (err, data) => {
if (err) {
console.error(err);
}
const permissions = {};
realm.write(() => {
data.forEach((item) => {
const permission = {
_id: item._id,
roles: []
};
permission._server = { id: reduxStore.getState().server.server };
item.roles.forEach((role) => {
permission.roles.push({ value: role });
});
realm.create('permissions', permission, true);
permissions[item._id] = permission;
});
});
reduxStore.dispatch(actions.setAllPermissions(permissions));
});
Meteor.ddp.on('changed', (ddbMessage) => {
if (ddbMessage.collection === 'stream-room-messages') {
realm.write(() => {
@ -483,6 +506,9 @@ const RocketChat = {
return resolve(result[0]);
});
},
getRoomRoles(rid) {
return call('getRoomRoles', { rid });
},
async getPermalink(message) {
return new Promise(async(resolve, reject) => {
let room;

View File

@ -7,8 +7,8 @@ import server from './server';
import navigator from './navigator';
import createChannel from './createChannel';
import app from './app';
import permissions from './permissions';
export default combineReducers({
settings, login, meteor, messages, server, navigator, createChannel, app
settings, login, meteor, messages, server, navigator, createChannel, app, permissions
});

View File

@ -39,6 +39,12 @@ export default function messages(state = initialState, action) {
message: {},
editing: false
};
case types.MESSAGES.EDIT_FAILURE:
return {
...state,
message: {},
editing: false
};
case types.MESSAGES.PERMALINK_SUCCESS:
return {
...state,

View File

@ -0,0 +1,17 @@
import * as types from '../constants/types';
const initialState = {
settings: {}
};
export default function settings(state = initialState, action) {
switch (action.type) {
case types.SET_ALL_PERMISSIONS:
return {
...state,
...action.payload
};
default:
return state;
}
}

33
app/reducers/roomRoles.js Normal file
View File

@ -0,0 +1,33 @@
import * as types from '../actions/actionsTypes';
const initialState = {
isFetching: false,
failure: false,
roles: []
};
export default function login(state = initialState, action) {
switch (action.type) {
case types.ROOM_ROLES.REQUEST:
return {
...state,
isFetching: true,
roles: []
};
case types.ROOM_ROLES.SUCCESS:
return {
...state,
isFetching: false,
roles: action.roles
};
case types.ROOM_ROLES.FAILURE:
return {
...state,
isFetching: false,
failure: true,
roles: []
};
default:
return state;
}
}