mirror of
https://github.com/haiwen/seahub.git
synced 2025-05-14 02:45:44 +00:00
Add scan Wechat qrcode to join group (#7098)
* 01 frontend support wechat entry * 02 change backend settings * 03 update icon * 04 change wechat icon
This commit is contained in:
parent
bacc9e2aa5
commit
4da1b47664
frontend/src
components
css
utils
media
css/sf_font3
img
seahub
@ -2,7 +2,7 @@ import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ModalPortal from './modal-portal';
|
||||
import { Link } from '@gatsbyjs/reach-router';
|
||||
import { gettext, siteRoot, canInvitePeople, enableTC, sideNavFooterCustomHtml,
|
||||
import { gettext, siteRoot, canInvitePeople, enableTC, sideNavFooterCustomHtml, showWechatSupportGroup,
|
||||
isDocs, isPro, isDBSqlite3, customNavItems, mediaUrl, curNoteMsg } from '../utils/constants';
|
||||
import { SIDE_PANEL_FOLDED_WIDTH, SUB_NAV_ITEM_HEIGHT } from '../constants';
|
||||
import Tip from './side-nav-icon-tip';
|
||||
@ -13,6 +13,8 @@ import { Utils } from '../utils/utils';
|
||||
import Group from '../models/group';
|
||||
import toaster from './toast';
|
||||
import { FOLDED_SIDE_NAV_FILES, FOLDED_SIDE_NAV } from '../constants/zIndexes';
|
||||
import { isWorkWeixin } from './wechat/weixin-utils';
|
||||
import WechatDialog from './wechat/wechat-dialog';
|
||||
|
||||
|
||||
import '../css/main-side-nav-folded.css';
|
||||
@ -32,7 +34,9 @@ class MainSideNavFolded extends React.Component {
|
||||
groupItems: [],
|
||||
isFilesSubNavShown: false,
|
||||
isAboutDialogShow: false,
|
||||
isShowWechatDialog: false,
|
||||
};
|
||||
this.isWorkWeixin = isWorkWeixin(window.navigator.userAgent.toLowerCase());
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@ -53,6 +57,11 @@ class MainSideNavFolded extends React.Component {
|
||||
this.unsubscribeHeaderEvent();
|
||||
}
|
||||
|
||||
toggleWechatDialog = () => {
|
||||
this.setState({ isShowWechatDialog: !this.state.isShowWechatDialog });
|
||||
};
|
||||
|
||||
|
||||
handleOutsideClick = (e) => {
|
||||
const { isFilesSubNavShown } = this.state;
|
||||
if (isFilesSubNavShown && !this.filesSubNav.contains(e.target)) {
|
||||
@ -236,6 +245,14 @@ class MainSideNavFolded extends React.Component {
|
||||
<Tip target="main-side-nav-folded-about" text={gettext('About')} />
|
||||
</a>
|
||||
</li>
|
||||
{showWechatSupportGroup &&
|
||||
<li className='nav-item'>
|
||||
<a href="#" className="nav-link" onClick={this.toggleWechatDialog}>
|
||||
<span className="sf3-font-hi sf3-font mr-0" aria-hidden="true" id="main-side-nav-folded-wechat"></span>
|
||||
<Tip target="main-side-nav-folded-wechat" text={`加入 Seafile ${this.isWorkWeixin ? '企业' : ''}微信咨询群`} />
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
<div
|
||||
@ -252,6 +269,11 @@ class MainSideNavFolded extends React.Component {
|
||||
<AboutDialog onCloseAboutDialog={this.toggleAboutDialog} />
|
||||
</ModalPortal>
|
||||
)}
|
||||
{this.state.isShowWechatDialog &&
|
||||
<ModalPortal>
|
||||
<WechatDialog toggleWechatDialog={this.toggleWechatDialog}/>
|
||||
</ModalPortal>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { Link } from '@gatsbyjs/reach-router';
|
||||
import {
|
||||
gettext, siteRoot, canAddGroup, canAddRepo, canShareRepo,
|
||||
canGenerateShareLink, canGenerateUploadLink, canInvitePeople,
|
||||
enableTC, sideNavFooterCustomHtml, enableShowAbout,
|
||||
enableTC, sideNavFooterCustomHtml, enableShowAbout, showWechatSupportGroup,
|
||||
canViewOrg, isDocs, isPro, isDBSqlite3, customNavItems, mediaUrl
|
||||
} from '../utils/constants';
|
||||
import { seafileAPI } from '../utils/seafile-api';
|
||||
@ -16,6 +16,8 @@ import CreateGroupDialog from '../components/dialog/create-group-dialog';
|
||||
import AboutDialog from './dialog/about-dialog';
|
||||
import FilesSubNav from '../components/files-sub-nav';
|
||||
import { SUB_NAV_ITEM_HEIGHT } from '../constants';
|
||||
import { isWorkWeixin } from './wechat/weixin-utils';
|
||||
import WechatDialog from './wechat/wechat-dialog';
|
||||
|
||||
const propTypes = {
|
||||
currentTab: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
@ -33,11 +35,17 @@ class MainSideNav extends React.Component {
|
||||
sharedExtended: false,
|
||||
groupItems: [],
|
||||
isCreateGroupDialogOpen: false,
|
||||
isShowWechatDialog: false,
|
||||
};
|
||||
this.adminHeight = 0;
|
||||
this.filesNavHeight = 0;
|
||||
this.isWorkWeixin = isWorkWeixin(window.navigator.userAgent.toLowerCase());
|
||||
}
|
||||
|
||||
toggleWechatDialog = () => {
|
||||
this.setState({ isShowWechatDialog: !this.state.isShowWechatDialog });
|
||||
};
|
||||
|
||||
shExtend = () => {
|
||||
this.setState({
|
||||
sharedExtended: !this.state.sharedExtended,
|
||||
@ -305,6 +313,16 @@ class MainSideNav extends React.Component {
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
{showWechatSupportGroup &&
|
||||
<li className='nav-item'>
|
||||
<a href="#" className="nav-link" onClick={this.toggleWechatDialog}>
|
||||
<span className="sf3-font-hi sf3-font" aria-hidden="true"></span>
|
||||
<span className="nav-text">
|
||||
{`加入 Seafile ${this.isWorkWeixin ? '企业' : ''}微信咨询群`}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
@ -319,6 +337,11 @@ class MainSideNav extends React.Component {
|
||||
<AboutDialog onCloseAboutDialog={this.toggleAboutDialog} />
|
||||
</ModalPortal>
|
||||
)}
|
||||
{this.state.isShowWechatDialog &&
|
||||
<ModalPortal>
|
||||
<WechatDialog toggleWechatDialog={this.toggleWechatDialog}/>
|
||||
</ModalPortal>
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
40
frontend/src/components/wechat/wechat-dialog.js
Normal file
40
frontend/src/components/wechat/wechat-dialog.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Modal, ModalHeader, ModalBody } from 'reactstrap';
|
||||
import { mediaUrl } from '../../utils/constants';
|
||||
import { isWorkWeixin } from './weixin-utils';
|
||||
import '../../css/wechat-dialog.css';
|
||||
|
||||
const propTypes = {
|
||||
toggleWechatDialog: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
class WechatDialog extends React.PureComponent {
|
||||
|
||||
toggle = () => {
|
||||
this.props.toggleWechatDialog();
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Modal isOpen={true} toggle={this.toggle} zIndex='1060'>
|
||||
<ModalHeader toggle={this.toggle}>
|
||||
加入咨询群
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<div className="wechat-dialog-body">
|
||||
<img src={`${mediaUrl}img/wechat-QR-code.png`} width="150" alt="" />
|
||||
<div className="wechat-dialog-message">
|
||||
<p>扫描二维码</p>
|
||||
<p>{`加入 Seafile ${isWorkWeixin(window.navigator.userAgent.toLowerCase()) ? '企业' : ''}微信咨询群`}</p>
|
||||
</div>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WechatDialog.propTypes = propTypes;
|
||||
|
||||
export default WechatDialog;
|
6
frontend/src/components/wechat/weixin-utils.js
Normal file
6
frontend/src/components/wechat/weixin-utils.js
Normal file
@ -0,0 +1,6 @@
|
||||
export const isWorkWeixin = (ua) => {
|
||||
if (ua.includes('micromessenger') && ua.includes('wxwork')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
18
frontend/src/css/wechat-dialog.css
Normal file
18
frontend/src/css/wechat-dialog.css
Normal file
@ -0,0 +1,18 @@
|
||||
.wechat-dialog-body {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 3rem;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wechat-dialog-message {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 1rem;
|
||||
color: #212529;
|
||||
font-size: 14px;
|
||||
}
|
@ -105,6 +105,8 @@ export const enableFileTags = window.app.pageOptions.enableFileTags || false;
|
||||
|
||||
export const enableShowAbout = window.app.pageOptions.enableShowAbout || false;
|
||||
|
||||
export const showWechatSupportGroup = window.app.pageOptions.showWechatSupportGroup || false;
|
||||
|
||||
// dtable
|
||||
export const workspaceID = window.app.pageOptions.workspaceID;
|
||||
export const showLogoutIcon = window.app.pageOptions.showLogoutIcon;
|
||||
|
@ -1,14 +1,11 @@
|
||||
@font-face {
|
||||
font-family: "sf3-font";
|
||||
/* Project id 1230969 */
|
||||
src: url('iconfont.eot?t=1730358680866');
|
||||
/* IE9 */
|
||||
src: url('iconfont.eot?t=1730358680866#iefix') format('embedded-opentype'),
|
||||
/* IE6-IE8 */
|
||||
url('iconfont.woff2?t=1730358680866') format('woff2'),
|
||||
url('iconfont.woff?t=1730358680866') format('woff'),
|
||||
url('iconfont.ttf?t=1730358680866') format('truetype'),
|
||||
url('iconfont.svg?t=1730358680866#sf3-font') format('svg');
|
||||
font-family: "sf3-font"; /* Project id 1230969 */
|
||||
src: url('iconfont.eot?t=1732504469237'); /* IE9 */
|
||||
src: url('iconfont.eot?t=1732504469237#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url('iconfont.woff2?t=1732504469237') format('woff2'),
|
||||
url('iconfont.woff?t=1732504469237') format('woff'),
|
||||
url('iconfont.ttf?t=1732504469237') format('truetype'),
|
||||
url('iconfont.svg?t=1732504469237#sf3-font') format('svg');
|
||||
}
|
||||
|
||||
.sf3-font {
|
||||
@ -19,6 +16,26 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.sf3-font-hi:before {
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.sf3-font-refresh:before {
|
||||
content: "\e851";
|
||||
}
|
||||
|
||||
.sf3-font-current-location:before {
|
||||
content: "\e850";
|
||||
}
|
||||
|
||||
.sf3-font-ai_generated:before {
|
||||
content: "\e84f";
|
||||
}
|
||||
|
||||
.sf3-font-map:before {
|
||||
content: "\e84e";
|
||||
}
|
||||
|
||||
.sf3-font-photos-classfied-by-people:before {
|
||||
content: "\e84d";
|
||||
}
|
||||
@ -490,3 +507,4 @@
|
||||
.sf3-font-enterprise-wechat:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -14,6 +14,16 @@
|
||||
/>
|
||||
<missing-glyph />
|
||||
|
||||
<glyph glyph-name="hi" unicode="" d="M512 864c262.4 0 480-214.4 480-480 0-96-28.8-188.8-76.8-262.4l64-150.4c3.2-9.6 0-19.2-9.6-22.4-3.2 0-6.4-3.2-9.6 0l-172.8 44.8c-80-54.4-172.8-83.2-272-83.2C249.6-96 32 121.6 32 384S249.6 864 512 864zM512 528v-131.2H390.4V528h-64v-326.4h64V336H512v-134.4h60.8V528H512z m147.2-67.2c22.4 0 38.4 16 38.4 38.4 0 19.2-16 38.4-38.4 38.4-19.2 0-38.4-19.2-38.4-38.4 3.2-19.2 22.4-38.4 38.4-38.4z m-25.6-259.2h57.6V435.2h-57.6v-233.6z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="refresh" unicode="" d="M512 864c163.2 0 304-76.8 390.4-201.6V742.4c0 25.6 22.4 44.8 44.8 44.8S992 768 992 742.4v-179.2c0-25.6-22.4-44.8-44.8-44.8h-195.2c-16 0-32 9.6-38.4 22.4-9.6 16-9.6 35.2 0 48 6.4 12.8 22.4 19.2 38.4 19.2h76.8c-70.4 99.2-185.6 166.4-316.8 166.4C294.4 774.4 121.6 601.6 121.6 384S294.4-6.4 512-6.4c182.4 0 332.8 121.6 377.6 291.2 6.4 19.2 19.2 32 41.6 32 12.8 0 25.6-3.2 38.4-16 16-16 12.8-32 9.6-51.2C921.6 48 729.6-96 512-96 249.6-96 32 121.6 32 384S249.6 864 512 864z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="current-location" unicode="" d="M512 864c265.6 0 480-214.4 480-480s-214.4-480-480-480S32 118.4 32 384 246.4 864 512 864z m48-118.4v-96c0-25.6-22.4-48-48-48s-48 22.4-48 48v96c-160-22.4-288-150.4-310.4-310.4h96c25.6 0 48-22.4 48-48s-22.4-48-48-48h-96c22.4-163.2 150.4-291.2 310.4-313.6v99.2c0 25.6 22.4 48 48 48s48-22.4 48-48v-99.2c163.2 22.4 291.2 150.4 313.6 313.6h-99.2c-25.6 0-48 22.4-48 48s22.4 48 48 48h99.2c-22.4 160-153.6 288-313.6 310.4zM512 512c70.4 0 128-57.6 128-128s-57.6-128-128-128-128 57.6-128 128 57.6 128 128 128z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="ai_generated" unicode="" d="M486.4 896C214.4 883.2 0 659.2 0 384c0-115.2 35.2-220.8 105.6-313.6L6.4-105.6c-3.2-3.2-3.2-9.6 0-12.8 3.2-6.4 9.6-9.6 12.8-9.6H512c275.2 0 499.2 214.4 512 486.4 6.4 144-44.8 278.4-140.8 380.8S656 896 512 896h-25.6z m-121.6-288h102.4L640 160h-102.4l-41.6 102.4h-160L294.4 160H192l172.8 448z m336 0H800v-448h-99.2V608zM416 499.2l-60.8-156.8h118.4L416 499.2z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="map" unicode="" d="M976 646.4c9.6-6.4 16-19.2 16-32v-563.2c0-16-9.6-32-25.6-38.4l-281.6-105.6c-9.6-3.2-19.2-3.2-25.6 0L352 9.6l-265.6-102.4c-12.8-3.2-25.6-3.2-38.4 3.2-9.6 6.4-16 19.2-16 32V505.6c0 16 9.6 32 25.6 38.4l128 48c-6.4-35.2-6.4-73.6 0-108.8l-64-28.8v-428.8l179.2 76.8v172.8l89.6-112v-86.4l240-80v166.4l89.6 112v-256l179.2 70.4V531.2l-60.8-25.6c3.2 35.2 3.2 70.4-6.4 105.6l102.4 38.4c16 6.4 28.8 3.2 41.6-3.2zM297.6 777.6C416 892.8 604.8 892.8 723.2 777.6c105.6-99.2 118.4-256 35.2-374.4l-198.4-246.4-9.6-9.6c-28.8-22.4-67.2-19.2-89.6 9.6l-195.2 243.2c-83.2 118.4-67.2 275.2 32 377.6z m355.2-67.2c-76.8 70.4-204.8 70.4-281.6 0-70.4-64-76.8-163.2-22.4-236.8l131.2-176c16-22.4 48-22.4 64 0l131.2 176c54.4 73.6 48 172.8-22.4 236.8zM512 704c70.4 0 128-57.6 128-128 0-44.8-25.6-86.4-64-112s-89.6-22.4-128 0-64 64-64 112c0 70.4 57.6 128 128 128z m0-96c-19.2 0-32-12.8-32-32s12.8-32 32-32 32 12.8 32 32-12.8 32-32 32z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="photos-classfied-by-people" unicode="" d="M438.4 336c44.8-25.6 99.2-25.6 144 0s73.6 73.6 73.6 124.8c0 80-64 144-144 144s-144-64-144-144c0-51.2 25.6-99.2 70.4-124.8zM832 70.4c0-51.2-144-124.8-297.6-128-166.4 0-342.4 73.6-342.4 128 0 105.6 144 169.6 320 169.6s320-64 320-169.6zM512 896c281.6 0 512-230.4 512-512s-230.4-512-512-512S0 102.4 0 384 230.4 896 512 896z m0-96C281.6 800 96 614.4 96 384s185.6-416 416-416 416 185.6 416 416S742.4 800 512 800z" horiz-adv-x="1024" />
|
||||
|
||||
<glyph glyph-name="Kanban" unicode="" d="M896 832c54.4 0 96-41.6 96-96v-480c0-54.4-41.6-96-96-96h-160v-128c0-54.4-41.6-96-96-96h-256c-54.4 0-96 41.6-96 96V352H128c-54.4 0-96 41.6-96 96V736c0 54.4 41.6 96 96 96h768z m-256-96h-256v-704h256V736z m256 0h-160v-480h160V736zM288 736H128v-288h160V736z" horiz-adv-x="1024" />
|
||||
|
Before (image error) Size: 74 KiB After (image error) Size: 76 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
media/img/wechat-QR-code.png
Normal file
BIN
media/img/wechat-QR-code.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 4.6 KiB |
@ -501,6 +501,9 @@ ADMIN_LOGS_EXPORT_MAX_DAYS = 180
|
||||
# Enable show about module
|
||||
ENABLE_SHOW_ABOUT = True
|
||||
|
||||
# enable show wechat support
|
||||
SHOW_WECHAT_SUPPORT_GROUP = False
|
||||
|
||||
# File preview
|
||||
FILE_PREVIEW_MAX_SIZE = 30 * 1024 * 1024
|
||||
FILE_ENCODING_LIST = ['auto', 'utf-8', 'gbk', 'ISO-8859-1', 'ISO-8859-5']
|
||||
|
@ -157,6 +157,7 @@
|
||||
enableMetadataManagement: {% if enable_metadata_management %} true {% else %} false {% endif %},
|
||||
enableFileTags: {% if enable_file_tags %} true {% else %} false {% endif %},
|
||||
enableShowAbout: {% if enable_show_about %} true {% else %} false {% endif %},
|
||||
showWechatSupportGroup: {% if show_wechat_support_group %} true {% else %} false {% endif %},
|
||||
baiduMapKey: '{{ baidu_map_key }}',
|
||||
googleMapKey: '{{ google_map_key }}',
|
||||
googleMapId: '{{ google_map_id }}',
|
||||
|
@ -53,12 +53,12 @@ from seahub.utils.timeutils import utc_to_local
|
||||
from seahub.utils.auth import get_login_bg_image_path
|
||||
import seahub.settings as settings
|
||||
from seahub.settings import AVATAR_FILE_STORAGE, ENABLE_REPO_SNAPSHOT_LABEL, \
|
||||
SHARE_LINK_EXPIRE_DAYS_MIN, \
|
||||
SHARE_LINK_EXPIRE_DAYS_MIN, ENABLE_METADATA_MANAGEMENT, \
|
||||
SHARE_LINK_EXPIRE_DAYS_MAX, SHARE_LINK_EXPIRE_DAYS_DEFAULT, \
|
||||
UPLOAD_LINK_EXPIRE_DAYS_MIN, UPLOAD_LINK_EXPIRE_DAYS_MAX, UPLOAD_LINK_EXPIRE_DAYS_DEFAULT, \
|
||||
SEAFILE_COLLAB_SERVER, ENABLE_RESET_ENCRYPTED_REPO_PASSWORD, \
|
||||
ADDITIONAL_SHARE_DIALOG_NOTE, ADDITIONAL_ABOUT_DIALOG_LINKS, \
|
||||
DTABLE_WEB_SERVER, SEADOC_SERVER_URL
|
||||
DTABLE_WEB_SERVER, SEADOC_SERVER_URL, SHOW_WECHAT_SUPPORT_GROUP
|
||||
|
||||
from seahub.ocm.settings import ENABLE_OCM, OCM_REMOTE_SERVERS
|
||||
from seahub.ocm_via_webdav.settings import ENABLE_OCM_VIA_WEBDAV
|
||||
@ -1140,19 +1140,20 @@ def react_fake_view(request, **kwargs):
|
||||
'enable_ocm_via_webdav': ENABLE_OCM_VIA_WEBDAV,
|
||||
'enable_ocm': ENABLE_OCM,
|
||||
'ocm_remote_servers': OCM_REMOTE_SERVERS,
|
||||
'show_wechat_support_group': SHOW_WECHAT_SUPPORT_GROUP,
|
||||
'enable_share_to_department': settings.ENABLE_SHARE_TO_DEPARTMENT,
|
||||
'enable_video_thumbnail': settings.ENABLE_VIDEO_THUMBNAIL,
|
||||
'enable_pdf_thumbnail': settings.ENABLE_PDF_THUMBNAIL,
|
||||
'group_import_members_extra_msg': GROUP_IMPORT_MEMBERS_EXTRA_MSG,
|
||||
'request_from_onlyoffice_desktop_editor': ONLYOFFICE_DESKTOP_EDITOR_HTTP_USER_AGENT in request.headers.get('user-agent', ''),
|
||||
'enable_sso_to_thirdpart_website': settings.ENABLE_SSO_TO_THIRDPART_WEBSITE,
|
||||
'enable_metadata_management': settings.ENABLE_METADATA_MANAGEMENT,
|
||||
'enable_metadata_management': ENABLE_METADATA_MANAGEMENT,
|
||||
'enable_file_tags': settings.ENABLE_FILE_TAGS,
|
||||
'enable_show_about': settings.ENABLE_SHOW_ABOUT
|
||||
|
||||
}
|
||||
|
||||
if settings.ENABLE_METADATA_MANAGEMENT:
|
||||
if ENABLE_METADATA_MANAGEMENT:
|
||||
return_dict['baidu_map_key'] = settings.BAIDU_MAP_KEY
|
||||
return_dict['google_map_key'] = settings.GOOGLE_MAP_KEY
|
||||
return_dict['google_map_id'] = settings.GOOGLE_MAP_ID
|
||||
|
Loading…
Reference in New Issue
Block a user