Add user list to groups

This commit is contained in:
David Baker 2017-07-25 15:56:16 +01:00
parent b589fcc3b0
commit c2034d5335
22 changed files with 287 additions and 44 deletions

View File

@ -227,6 +227,7 @@ export default React.createClass({
const HomePage = sdk.getComponent('structures.HomePage'); const HomePage = sdk.getComponent('structures.HomePage');
const GroupView = sdk.getComponent('structures.GroupView'); const GroupView = sdk.getComponent('structures.GroupView');
const MyGroups = sdk.getComponent('structures.MyGroups'); const MyGroups = sdk.getComponent('structures.MyGroups');
const GroupMemberList = sdk.getComponent('groups.GroupMemberList');
const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar'); const MatrixToolbar = sdk.getComponent('globals.MatrixToolbar');
const NewVersionBar = sdk.getComponent('globals.NewVersionBar'); const NewVersionBar = sdk.getComponent('globals.NewVersionBar');
const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar'); const UpdateCheckBar = sdk.getComponent('globals.UpdateCheckBar');
@ -307,6 +308,7 @@ export default React.createClass({
page_element = <GroupView page_element = <GroupView
groupId={this.props.currentGroupId} groupId={this.props.currentGroupId}
/>; />;
right_panel = <RightPanel groupId={this.props.currentGroupId} opacity={this.props.rightOpacity} />;
break; break;
} }

View File

@ -14,10 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
'use strict'; import React from 'react';
import AvatarLogic from '../../../Avatar';
var React = require('react');
var AvatarLogic = require("../../../Avatar");
import sdk from '../../../index'; import sdk from '../../../index';
import AccessibleButton from '../elements/AccessibleButton'; import AccessibleButton from '../elements/AccessibleButton';

View File

@ -0,0 +1,146 @@
/*
Copyright 2017 Vector Creations 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 Promise from 'bluebird';
import sdk from '../../../index';
import GeminiScrollbar from 'react-gemini-scrollbar';
import PropTypes from 'prop-types';
import withMatrixClient from '../../../wrappers/withMatrixClient';
const INITIAL_LOAD_NUM_MEMBERS = 30;
export default withMatrixClient(React.createClass({
displayName: 'GroupMemberList',
propTypes: {
matrixClient: PropTypes.object.isRequired,
groupId: PropTypes.string.isRequired,
},
getInitialState: function() {
return {
fetching: false,
members: null,
}
},
componentWillMount: function() {
this._unmounted = false;
this._fetchMembers();
},
_fetchMembers: function() {
this.setState({fetching: true});
this.props.matrixClient.getGroupUsers(this.props.groupId).then((result) => {
this.setState({
members: result.chunk,
fetching: false,
});
}).catch((e) => {
this.setState({fetching: false});
console.error("Failed to get group member list: " + e);
});
},
_createOverflowTile: function(overflowCount, totalCount) {
// For now we'll pretend this is any entity. It should probably be a separate tile.
const EntityTile = sdk.getComponent("rooms.EntityTile");
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
const text = _t("and %(count)s others...", { count: overflowCount });
return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} />
} name={text} presenceState="online" suppressOnHover={true}
onClick={this._showFullMemberList} />
);
},
_showFullMemberList: function() {
this.setState({
truncateAt: -1
});
},
onSearchQueryChanged: function(ev) {
this.setState({ searchQuery: ev.target.value });
},
makeGroupMemberTiles: function(query) {
const GroupMemberTile = sdk.getComponent("groups.GroupMemberTile");
query = (query || "").toLowerCase();
const memberList = this.state.members.filter((m) => {
if (query) {
//const matchesName = m.name.toLowerCase().indexOf(query) !== -1;
const matchesId = m.user_id.toLowerCase().indexOf(query) !== -1;
if (/*!matchesName &&*/ !matchesId) {
return false;
}
}
return true;
}).map(function(m) {
return (
<GroupMemberTile key={m.user_id} member={m} />
);
});
memberList.sort((a, b) => {
// should put admins at the top: we don't yet have that info
if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else {
return 0;
}
});
return memberList;
},
render: function() {
if (this.state.fetching) {
const Spinner = sdk.getComponent("elements.Spinner");
return <Spinner />;
} else if (this.state.members === null) {
return null;
}
const inputBox = (
<form autoComplete="off">
<input className="mx_MemberList_query" id="mx_MemberList_query" type="text"
onChange={this.onSearchQueryChanged} value={this.state.searchQuery}
placeholder={ _t('Filter group members') } />
</form>
);
const TruncatedList = sdk.getComponent("elements.TruncatedList");
return (
<div className="mx_MemberList">
{ inputBox }
<GeminiScrollbar autoshow={true} className="mx_MemberList_joined mx_MemberList_outerWrapper">
<TruncatedList className="mx_MemberList_wrapper" truncateAt={this.state.truncateAt}
createOverflowElement={this._createOverflowTile}>
{this.makeGroupMemberTiles(this.state.searchQuery)}
</TruncatedList>
</GeminiScrollbar>
</div>
);
}
}));

View File

@ -0,0 +1,68 @@
/*
Copyright 2017 Vector Creations 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 PropTypes from 'prop-types';
import sdk from '../../../index';
import dis from '../../../dispatcher';
import { _t } from '../../../languageHandler';
import withMatrixClient from '../../../wrappers/withMatrixClient';
import Matrix from "matrix-js-sdk";
export default withMatrixClient(React.createClass({
displayName: 'GroupMemberTile',
propTypes: {
matrixClient: PropTypes.object,
member: PropTypes.shape({
user_id: PropTypes.string.isRequired,
}).isRequired,
},
getInitialState: function() {
return {};
},
onClick: function(e) {
const member = new Matrix.RoomMember(null, this.props.member.user_id);
dis.dispatch({
action: 'view_user',
member: member,
});
},
getPowerLabel: function() {
return _t("%(userName)s (power %(powerLevelNumber)s)", {userName: this.props.member.userId, powerLevelNumber: this.props.member.powerLevel});
},
render: function() {
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
const EntityTile = sdk.getComponent('rooms.EntityTile');
const name = this.props.member.user_id;
const av = (
<BaseAvatar name={this.props.member.user_id} width={36} height={36} />
);
return (
<EntityTile presenceState="online"
avatarJsx={av} title={this.getPowerLabel()} onClick={this.onClick}
name={name} powerLevel={0} suppressOnHover={true}
/>
);
}
}));

View File

@ -1,5 +1,6 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -200,11 +201,9 @@ module.exports = React.createClass({
_createOverflowTile: function(overflowCount, totalCount) { _createOverflowTile: function(overflowCount, totalCount) {
// For now we'll pretend this is any entity. It should probably be a separate tile. // For now we'll pretend this is any entity. It should probably be a separate tile.
var EntityTile = sdk.getComponent("rooms.EntityTile"); const EntityTile = sdk.getComponent("rooms.EntityTile");
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
var text = (overflowCount > 1) const text = _t("and %(count)s others...", { count: overflowCount });
? _t("and %(overflowCount)s others...", { overflowCount: overflowCount })
: _t("and one other...");
return ( return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={ <EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} /> <BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} />

View File

@ -117,9 +117,7 @@ var SearchableEntityList = React.createClass({
_createOverflowEntity: function(overflowCount, totalCount) { _createOverflowEntity: function(overflowCount, totalCount) {
var EntityTile = sdk.getComponent("rooms.EntityTile"); var EntityTile = sdk.getComponent("rooms.EntityTile");
var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); var BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
var text = (overflowCount > 1) const text = _t("and %(count)s others...", { count: overflowCount });
? _t("and %(overflowCount)s others...", { overflowCount: overflowCount })
: _t("and one other...");
return ( return (
<EntityTile className="mx_EntityTile_ellipsis" avatarJsx={ <EntityTile className="mx_EntityTile_ellipsis" avatarJsx={
<BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} /> <BaseAvatar url="img/ellipsis.svg" name="..." width={36} height={36} />

View File

@ -552,8 +552,10 @@
"Failed to forget room %(errCode)s": "Das Entfernen des Raums ist fehlgeschlagen %(errCode)s", "Failed to forget room %(errCode)s": "Das Entfernen des Raums ist fehlgeschlagen %(errCode)s",
"Failed to join the room": "Fehler beim Betreten des Raumes", "Failed to join the room": "Fehler beim Betreten des Raumes",
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Eine Textnachricht wurde an +%(msisdn)s gesendet. Bitte gebe den Verifikationscode ein, den er beinhaltet", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "Eine Textnachricht wurde an +%(msisdn)s gesendet. Bitte gebe den Verifikationscode ein, den er beinhaltet",
"and %(overflowCount)s others...": "und %(overflowCount)s weitere...", "and %(count)s others...": {
"and one other...": "und ein(e) weitere(r)...", "other": "und %(count)s weitere...",
"one": "und ein(e) weitere(r)..."
},
"Are you sure?": "Bist du sicher?", "Are you sure?": "Bist du sicher?",
"Attachment": "Anhang", "Attachment": "Anhang",
"Ban": "Dauerhaft aus dem Raum ausschließen", "Ban": "Dauerhaft aus dem Raum ausschließen",

View File

@ -175,8 +175,10 @@
"an address": "μία διεύθηνση", "an address": "μία διεύθηνση",
"%(items)s and %(remaining)s others": "%(items)s και %(remaining)s ακόμα", "%(items)s and %(remaining)s others": "%(items)s και %(remaining)s ακόμα",
"%(items)s and one other": "%(items)s και ένας ακόμα", "%(items)s and one other": "%(items)s και ένας ακόμα",
"and %(overflowCount)s others...": "και %(overflowCount)s άλλοι...", "and %(count)s others...": {
"and one other...": "και ένας ακόμα...", "other": "και %(count)s άλλοι...",
"one": "και ένας ακόμα..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s και %(lastPerson)s γράφουν", "%(names)s and %(lastPerson)s are typing": "%(names)s και %(lastPerson)s γράφουν",
"%(names)s and one other are typing": "%(names)s και ένας ακόμα γράφουν", "%(names)s and one other are typing": "%(names)s και ένας ακόμα γράφουν",
"%(names)s and %(count)s others are typing": "%(names)s και %(count)s άλλοι γράφουν", "%(names)s and %(count)s others are typing": "%(names)s και %(count)s άλλοι γράφουν",

View File

@ -157,8 +157,10 @@
"%(items)s and %(remaining)s others": "%(items)s and %(remaining)s others", "%(items)s and %(remaining)s others": "%(items)s and %(remaining)s others",
"%(items)s and one other": "%(items)s and one other", "%(items)s and one other": "%(items)s and one other",
"%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s",
"and %(overflowCount)s others...": "and %(overflowCount)s others...", "and %(count)s others...": {
"and one other...": "and one other...", "other": "and %(count)s others...",
"one": "and one other..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing",
"%(names)s and one other are typing": "%(names)s and one other are typing", "%(names)s and one other are typing": "%(names)s and one other are typing",
"%(names)s and %(count)s others are typing": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing": "%(names)s and %(count)s others are typing",

View File

@ -154,8 +154,10 @@
"%(items)s and %(remaining)s others": "%(items)s and %(remaining)s others", "%(items)s and %(remaining)s others": "%(items)s and %(remaining)s others",
"%(items)s and one other": "%(items)s and one other", "%(items)s and one other": "%(items)s and one other",
"%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s and %(lastItem)s",
"and %(overflowCount)s others...": "and %(overflowCount)s others...", "and %(count)s others...": {
"and one other...": "and one other...", "other": "and %(count)s others...",
"one": "and one other..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing", "%(names)s and %(lastPerson)s are typing": "%(names)s and %(lastPerson)s are typing",
"%(names)s and one other are typing": "%(names)s and one other are typing", "%(names)s and one other are typing": "%(names)s and one other are typing",
"%(names)s and %(count)s others are typing": "%(names)s and %(count)s others are typing", "%(names)s and %(count)s others are typing": "%(names)s and %(count)s others are typing",

View File

@ -140,8 +140,10 @@
"%(items)s and %(remaining)s others": "%(items)s y %(remaining)s otros", "%(items)s and %(remaining)s others": "%(items)s y %(remaining)s otros",
"%(items)s and one other": "%(items)s y otro", "%(items)s and one other": "%(items)s y otro",
"%(items)s and %(lastItem)s": "%(items)s y %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s y %(lastItem)s",
"and %(overflowCount)s others...": "y %(overflowCount)s otros...", "and %(count)s others...": {
"and one other...": "y otro...", "other": "y %(count)s otros...",
"one": "y otro..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s y %(lastPerson)s están escribiendo", "%(names)s and %(lastPerson)s are typing": "%(names)s y %(lastPerson)s están escribiendo",
"%(names)s and one other are typing": "%(names)s y otro están escribiendo", "%(names)s and one other are typing": "%(names)s y otro están escribiendo",
"%(names)s and %(count)s others are typing": "%(names)s y %(count)s otros están escribiendo", "%(names)s and %(count)s others are typing": "%(names)s y %(count)s otros están escribiendo",

View File

@ -188,8 +188,10 @@
"%(items)s and %(remaining)s others": "%(items)s et %(remaining)s autres", "%(items)s and %(remaining)s others": "%(items)s et %(remaining)s autres",
"%(items)s and one other": "%(items)s et un autre", "%(items)s and one other": "%(items)s et un autre",
"%(items)s and %(lastItem)s": "%(items)s et %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s et %(lastItem)s",
"and %(overflowCount)s others...": "et %(overflowCount)s autres...", "and %(count)s others...": {
"and one other...": "et un autre...", "other": "et %(count)s autres...",
"one": "et un autre..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s et %(lastPerson)s sont en train de taper", "%(names)s and %(lastPerson)s are typing": "%(names)s et %(lastPerson)s sont en train de taper",
"%(names)s and one other are typing": "%(names)s et un autre sont en train de taper", "%(names)s and one other are typing": "%(names)s et un autre sont en train de taper",
"%(names)s and %(count)s others are typing": "%(names)s et %(count)s d'autres sont en train de taper", "%(names)s and %(count)s others are typing": "%(names)s et %(count)s d'autres sont en train de taper",

View File

@ -190,8 +190,10 @@
"%(items)s and %(remaining)s others": "%(items)s és még: %(remaining)s", "%(items)s and %(remaining)s others": "%(items)s és még: %(remaining)s",
"%(items)s and one other": "%(items)s és még egy", "%(items)s and one other": "%(items)s és még egy",
"%(items)s and %(lastItem)s": "%(items)s és %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s és %(lastItem)s",
"and %(overflowCount)s others...": "és még: %(overflowCount)s ...", "and %(count)s others...": {
"and one other...": "és még egy...", "other": "és még: %(count)s ...",
"one": "és még egy..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s és %(lastPerson)s írnak", "%(names)s and %(lastPerson)s are typing": "%(names)s és %(lastPerson)s írnak",
"%(names)s and one other are typing": "%(names)s és még valaki ír", "%(names)s and one other are typing": "%(names)s és még valaki ír",
"%(names)s and %(count)s others are typing": "%(names)s és %(count)s ember ír", "%(names)s and %(count)s others are typing": "%(names)s és %(count)s ember ír",

View File

@ -225,8 +225,10 @@
"%(items)s and %(remaining)s others": "%(items)s과 %(remaining)s", "%(items)s and %(remaining)s others": "%(items)s과 %(remaining)s",
"%(items)s and one other": "%(items)s과 다른 하나", "%(items)s and one other": "%(items)s과 다른 하나",
"%(items)s and %(lastItem)s": "%(items)s과 %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s과 %(lastItem)s",
"and %(overflowCount)s others...": "그리고 %(overflowCount)s...", "and %(count)s others...": {
"and one other...": "그리고 다른 하나...", "other": "그리고 %(count)s...",
"one": "그리고 다른 하나..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s님과 %(lastPerson)s님이 입력중", "%(names)s and %(lastPerson)s are typing": "%(names)s님과 %(lastPerson)s님이 입력중",
"%(names)s and one other are typing": "%(names)s님과 다른 분이 입력중", "%(names)s and one other are typing": "%(names)s님과 다른 분이 입력중",
"%(names)s and %(count)s others are typing": "%(names)s님과 %(count)s 분들이 입력중", "%(names)s and %(count)s others are typing": "%(names)s님과 %(count)s 분들이 입력중",

View File

@ -141,8 +141,10 @@
"%(items)s and %(remaining)s others": "%(items)s en %(remaining)s andere", "%(items)s and %(remaining)s others": "%(items)s en %(remaining)s andere",
"%(items)s and one other": "%(items)s en één andere", "%(items)s and one other": "%(items)s en één andere",
"%(items)s and %(lastItem)s": "%(items)s en %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s en %(lastItem)s",
"and %(overflowCount)s others...": "en %(overflowCount)s andere...", "and %(count)s others...": {
"and one other...": "en één andere...", "other": "en %(count)s andere...",
"one": "en één andere..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s en %(lastPerson)s zijn aan het typen", "%(names)s and %(lastPerson)s are typing": "%(names)s en %(lastPerson)s zijn aan het typen",
"%(names)s and one other are typing": "%(names)s en één andere zijn aan het typen", "%(names)s and one other are typing": "%(names)s en één andere zijn aan het typen",
"%(names)s and %(count)s others are typing": "%(names)s en %(count)s andere zijn aan het typen", "%(names)s and %(count)s others are typing": "%(names)s en %(count)s andere zijn aan het typen",

View File

@ -556,8 +556,10 @@
"%(items)s and %(remaining)s others": "%(items)s e %(remaining)s outros", "%(items)s and %(remaining)s others": "%(items)s e %(remaining)s outros",
"%(items)s and one other": "%(items)s e um outro", "%(items)s and one other": "%(items)s e um outro",
"%(items)s and %(lastItem)s": "%(items)s e %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s e %(lastItem)s",
"and %(overflowCount)s others...": "e %(overflowCount)s outros...", "and %(count)s others...": {
"and one other...": "e um outro...", "other": "e %(count)s outros...",
"one": "e um outro..."
},
"Are you sure?": "Você tem certeza?", "Are you sure?": "Você tem certeza?",
"Attachment": "Anexo", "Attachment": "Anexo",
"Autoplay GIFs and videos": "Reproduzir automaticamente GIFs e videos", "Autoplay GIFs and videos": "Reproduzir automaticamente GIFs e videos",

View File

@ -557,8 +557,10 @@
"%(items)s and %(remaining)s others": "%(items)s e %(remaining)s outros", "%(items)s and %(remaining)s others": "%(items)s e %(remaining)s outros",
"%(items)s and one other": "%(items)s e um outro", "%(items)s and one other": "%(items)s e um outro",
"%(items)s and %(lastItem)s": "%(items)s e %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s e %(lastItem)s",
"and %(overflowCount)s others...": "e %(overflowCount)s outros...", "and %(count)s others...": {
"and one other...": "e um outro...", "other": "e %(count)s outros...",
"one": "e um outro..."
},
"Are you sure?": "Você tem certeza?", "Are you sure?": "Você tem certeza?",
"Attachment": "Anexo", "Attachment": "Anexo",
"Autoplay GIFs and videos": "Reproduzir automaticamente GIFs e videos", "Autoplay GIFs and videos": "Reproduzir automaticamente GIFs e videos",

View File

@ -448,7 +448,10 @@
"sx": "Суту", "sx": "Суту",
"zh-hk": "Китайский (Гонконг)", "zh-hk": "Китайский (Гонконг)",
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "На +%(msisdn)s было отправлено текстовое сообщение. Пожалуйста, введите проверочный код из него", "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains": "На +%(msisdn)s было отправлено текстовое сообщение. Пожалуйста, введите проверочный код из него",
"and %(overflowCount)s others...": "и %(overflowCount)s других...", "and %(count)s others...": {
"other": "и %(count)s других...",
"one": "и ещё один..."
},
"Are you sure?": "Вы уверены?", "Are you sure?": "Вы уверены?",
"Autoplay GIFs and videos": "Проигрывать GIF и видео автоматически", "Autoplay GIFs and videos": "Проигрывать GIF и видео автоматически",
"Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.": "Невозможно соединиться с домашним сервером - проверьте своё соединение и убедитесь, что <a>SSL-сертификат вашего домашнего сервера</a> включён в доверяемые.", "Can't connect to homeserver - please check your connectivity and ensure your <a>homeserver's SSL certificate</a> is trusted.": "Невозможно соединиться с домашним сервером - проверьте своё соединение и убедитесь, что <a>SSL-сертификат вашего домашнего сервера</a> включён в доверяемые.",
@ -479,7 +482,6 @@
"%(items)s and %(remaining)s others": "%(items)s и другие %(remaining)s", "%(items)s and %(remaining)s others": "%(items)s и другие %(remaining)s",
"%(items)s and one other": "%(items)s и ещё один", "%(items)s and one other": "%(items)s и ещё один",
"%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s и %(lastItem)s",
"and one other...": "и ещё один...",
"An error has occurred.": "Произошла ошибка.", "An error has occurred.": "Произошла ошибка.",
"Attachment": "Вложение", "Attachment": "Вложение",
"Ban": "Запретить", "Ban": "Запретить",

View File

@ -150,8 +150,10 @@
"%(items)s and %(remaining)s others": "%(items)s och %(remaining)s andra", "%(items)s and %(remaining)s others": "%(items)s och %(remaining)s andra",
"%(items)s and one other": "%(items)s och en annan", "%(items)s and one other": "%(items)s och en annan",
"%(items)s and %(lastItem)s": "%(items)s och %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s och %(lastItem)s",
"and %(overflowCount)s others...": "och %(overflowCount)s andra...", "and %(count)s others...": {
"and one other...": "och en annan...", "other": "och %(count)s andra...",
"one": "och en annan..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s och %(lastPerson)s skriver", "%(names)s and %(lastPerson)s are typing": "%(names)s och %(lastPerson)s skriver",
"%(names)s and one other are typing": "%(names)s och en annan skriver", "%(names)s and one other are typing": "%(names)s och en annan skriver",
"%(names)s and %(count)s others are typing": "%(names)s och %(count)s andra skriver", "%(names)s and %(count)s others are typing": "%(names)s och %(count)s andra skriver",

View File

@ -98,8 +98,10 @@
"%(items)s and %(remaining)s others": "%(items)s และอีก %(remaining)s ผู้ใช้", "%(items)s and %(remaining)s others": "%(items)s และอีก %(remaining)s ผู้ใช้",
"%(items)s and one other": "%(items)s และอีกหนึ่งผู้ใช้", "%(items)s and one other": "%(items)s และอีกหนึ่งผู้ใช้",
"%(items)s and %(lastItem)s": "%(items)s และ %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s และ %(lastItem)s",
"and %(overflowCount)s others...": "และอีก %(overflowCount)s ผู้ใช้...", "and %(count)s others...": {
"and one other...": "และอีกหนึ่งผู้ใช้...", "other": "และอีก %(count)s ผู้ใช้...",
"one": "และอีกหนึ่งผู้ใช้..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s และ %(lastPerson)s กำลังพิมพ์", "%(names)s and %(lastPerson)s are typing": "%(names)s และ %(lastPerson)s กำลังพิมพ์",
"%(names)s and one other are typing": "%(names)s และอีกหนึ่งคนกำลังพิมพ์", "%(names)s and one other are typing": "%(names)s และอีกหนึ่งคนกำลังพิมพ์",
"%(names)s and %(count)s others are typing": "%(names)s และอีก %(count)s คนกำลังพิมพ์", "%(names)s and %(count)s others are typing": "%(names)s และอีก %(count)s คนกำลังพิมพ์",

View File

@ -156,8 +156,10 @@
"%(items)s and %(remaining)s others": "%(items)s ve %(remaining)s diğerleri", "%(items)s and %(remaining)s others": "%(items)s ve %(remaining)s diğerleri",
"%(items)s and one other": "%(items)s ve bir başkası", "%(items)s and one other": "%(items)s ve bir başkası",
"%(items)s and %(lastItem)s": "%(items)s ve %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s ve %(lastItem)s",
"and %(overflowCount)s others...": "ve %(overflowCount)s diğerleri...", "and %(count)s others...": {
"and one other...": "ve bir diğeri...", "other": "ve %(count)s diğerleri...",
"one": "ve bir diğeri..."
},
"%(names)s and %(lastPerson)s are typing": "%(names)s ve %(lastPerson)s yazıyorlar", "%(names)s and %(lastPerson)s are typing": "%(names)s ve %(lastPerson)s yazıyorlar",
"%(names)s and one other are typing": "%(names)s ve birisi yazıyor", "%(names)s and one other are typing": "%(names)s ve birisi yazıyor",
"%(names)s and %(count)s others are typing": "%(names)s ve %(count)s diğeri yazıyor", "%(names)s and %(count)s others are typing": "%(names)s ve %(count)s diğeri yazıyor",

View File

@ -239,8 +239,10 @@
"%(items)s and %(remaining)s others": "%(items)s 和其它 %(remaining)s 个", "%(items)s and %(remaining)s others": "%(items)s 和其它 %(remaining)s 个",
"%(items)s and one other": "%(items)s 和其它一个", "%(items)s and one other": "%(items)s 和其它一个",
"%(items)s and %(lastItem)s": "%(items)s 和 %(lastItem)s", "%(items)s and %(lastItem)s": "%(items)s 和 %(lastItem)s",
"and %(overflowCount)s others...": "和其它 %(overflowCount)s 个...", "and %(count)s others...": {
"and one other...": "和其它一个...", "other": "和其它 %(count)s 个...",
"one": "和其它一个..."
},
"%(names)s and one other are typing": "%(names)s 和另一个人正在打字", "%(names)s and one other are typing": "%(names)s 和另一个人正在打字",
"anyone": "任何人", "anyone": "任何人",
"Anyone": "任何人", "Anyone": "任何人",