Fix permalink to not joined channels and to not fetched posts. (#6294)
* Fix permalink to not joined channels and to not fetched posts. * i18n-extract * Implement as designed * Revert unintended change * Minor fix and fix svgs * updated svg to fix masking problems and colors * Fix lint * Address feedback * Update join_public_channel.tsx fixed public channel svg * Update join_public_channel.tsx * Update join_private_channel.tsx * Address feedback Co-authored-by: Matthew Birtch <mattbirtch@gmail.com>
This commit is contained in:
parent
1ca401ef3c
commit
ee3b655991
12 changed files with 750 additions and 89 deletions
|
|
@ -1,11 +1,8 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {fetchMyChannelsForTeam} from '@actions/remote/channel';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {getCommonSystemValues} from '@queries/servers/system';
|
||||
import {getTeamById, getTeamByName} from '@queries/servers/team';
|
||||
import {permalinkBadTeam} from '@utils/draft';
|
||||
import {getCurrentTeam} from '@queries/servers/team';
|
||||
import {displayPermalink} from '@utils/permalink';
|
||||
import {PERMALINK_GENERIC_TEAM_NAME_REDIRECT} from '@utils/url';
|
||||
|
||||
|
|
@ -21,30 +18,14 @@ export const showPermalink = async (serverUrl: string, teamName: string, postId:
|
|||
try {
|
||||
let name = teamName;
|
||||
let team: TeamModel | undefined;
|
||||
const system = await getCommonSystemValues(database);
|
||||
if (!name || name === PERMALINK_GENERIC_TEAM_NAME_REDIRECT) {
|
||||
team = await getTeamById(database, system.currentTeamId);
|
||||
team = await getCurrentTeam(database);
|
||||
if (team) {
|
||||
name = team.name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!team) {
|
||||
team = await getTeamByName(database, name);
|
||||
if (!team) {
|
||||
permalinkBadTeam(intl);
|
||||
return {error: 'Bad Permalink team'};
|
||||
}
|
||||
}
|
||||
|
||||
if (team.id !== system.currentTeamId) {
|
||||
const result = await fetchMyChannelsForTeam(serverUrl, team.id, true, 0, false, true);
|
||||
if (result.error) {
|
||||
return {error: result.error};
|
||||
}
|
||||
}
|
||||
|
||||
await displayPermalink(team.name, postId, openAsPermalink);
|
||||
await displayPermalink(name, postId, openAsPermalink);
|
||||
|
||||
return {error: undefined};
|
||||
} catch (error) {
|
||||
|
|
|
|||
149
app/components/illustrations/join_private_channel.tsx
Normal file
149
app/components/illustrations/join_private_channel.tsx
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import * as React from 'react';
|
||||
import Svg, {
|
||||
Path,
|
||||
Mask,
|
||||
G,
|
||||
EMaskUnits,
|
||||
} from 'react-native-svg';
|
||||
|
||||
type Props = {
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
function SvgComponent({theme}: Props) {
|
||||
return (
|
||||
<Svg
|
||||
width={200}
|
||||
height={201}
|
||||
fill='none'
|
||||
viewBox='0 0 210 170'
|
||||
>
|
||||
<Path
|
||||
d='M20.215 68.747h41.93a5.84 5.84 0 0 1 4.143 1.704 5.864 5.864 0 0 1 1.727 4.14v26.71a5.879 5.879 0 0 1-1.727 4.141 5.842 5.842 0 0 1-4.144 1.704h-6.188v9.998l-9.281-9.998H20.23a5.857 5.857 0 0 1-4.143-1.704 5.871 5.871 0 0 1-1.728-4.141v-26.71a5.871 5.871 0 0 1 1.722-4.135 5.844 5.844 0 0 1 4.134-1.709Z'
|
||||
fill={theme.buttonBg}
|
||||
/>
|
||||
<Path
|
||||
d='M46.675 107.146H20.23a5.857 5.857 0 0 1-4.143-1.704 5.871 5.871 0 0 1-1.728-4.141V85.086s1.846 14.994 2.178 16.314c.332 1.32.99 3.295 4.109 3.622 3.119.328 26.029 2.124 26.029 2.124Z'
|
||||
fill='#000'
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M55.501 84.128a3.77 3.77 0 0 0-3.49 2.337 3.795 3.795 0 0 0 .82 4.126 3.774 3.774 0 0 0 6.447-2.677 3.787 3.787 0 0 0-2.33-3.499 3.764 3.764 0 0 0-1.447-.287ZM41.18 84.128a3.77 3.77 0 0 0-3.49 2.337 3.794 3.794 0 0 0 .819 4.126 3.775 3.775 0 0 0 4.116.82 3.78 3.78 0 0 0 2.331-3.497 3.79 3.79 0 0 0-1.104-2.678 3.772 3.772 0 0 0-2.673-1.108ZM26.873 84.128a3.77 3.77 0 0 0-3.493 2.334 3.793 3.793 0 0 0 .816 4.127 3.774 3.774 0 0 0 6.45-2.675 3.787 3.787 0 0 0-2.328-3.498 3.764 3.764 0 0 0-1.445-.288Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M63.664 79.93a11.918 11.918 0 0 0-5.668-7.174.411.411 0 0 1 .168-.779c2.644-.159 7.98.407 6.307 7.914a.417.417 0 0 1-.807.04Z'
|
||||
fill='#fff'
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M207.944 110.447c0 36.185-29.205 65.518-65.232 65.518-36.026 0-65.231-29.333-65.231-65.518 0-36.184 29.205-65.518 65.231-65.518 36.027 0 65.232 29.334 65.232 65.518Zm-.637 0c0 35.832-28.92 64.879-64.595 64.879-35.674 0-64.595-29.047-64.595-64.879 0-35.832 28.921-64.879 64.595-64.879 35.675 0 64.595 29.047 64.595 64.879Z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M142.712 175.326c35.675 0 64.595-29.047 64.595-64.879 0-35.832-28.92-64.879-64.595-64.879s-64.595 29.047-64.595 64.879c0 35.832 28.92 64.879 64.595 64.879Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M142.712 175.326c35.675 0 64.595-29.047 64.595-64.879 0-35.832-28.92-64.879-64.595-64.879s-64.595 29.047-64.595 64.879c0 35.832 28.92 64.879 64.595 64.879Z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M155.792 71.637c2.437-.51 6.786-.958 9.91.984 2.029 1.263 3.191 3.507 4.631 5.416 1.631 2.156 3.689 3.97 5.408 6.063 5.246 6.395 6.965 15.552 4.378 23.427-.823 2.499-2.039 4.863-2.694 7.409-.83 3.229-.716 6.611-.976 9.933-.694 9.229-4.142 17.993-7.549 26.587-1.023 2.58-2.087 5.226-3.98 7.248-3.074 3.282-8.243 4.369-12.369 2.604-2.995-1.284-5.377-3.873-8.52-4.731-1.497-.407-3.073-.393-4.618-.532-7.869-.718-15.183-5.787-18.628-12.915-3.446-7.128-2.891-16.048 1.411-22.69 1.431-2.213 3.234-4.16 5.008-6.093l9.082-9.821c2.301-2.486 4.677-5.104 5.602-8.371.679-2.395.515-4.946.715-7.425.384-4.678 2.194-9.342 5.539-12.614 3.346-3.272 5.487-4.026 7.65-4.479Z'
|
||||
fill='#6F370B'
|
||||
/>
|
||||
<Mask
|
||||
id='a'
|
||||
maskUnits={'userSpaceOnUse' as EMaskUnits.USER_SPACE_ON_USE}
|
||||
x={76}
|
||||
y={43}
|
||||
width={134}
|
||||
height={135}
|
||||
>
|
||||
<Path
|
||||
d='M142.712 176.326c36.231 0 65.595-29.499 65.595-65.879 0-36.38-29.364-65.879-65.595-65.879-36.231 0-65.595 29.5-65.595 65.879 0 36.38 29.364 65.879 65.595 65.879Z'
|
||||
fill='#FFFFFF'
|
||||
/>
|
||||
</Mask>
|
||||
<G mask='url(#a)'>
|
||||
<Path
|
||||
d='m156.679 118.534-8.794 18.965c-.238.515-.029 1.677.477 1.916 8.155 3.722 11.617 7.744 12.977 9.222a511.194 511.194 0 0 1 17.795 20.405c4.462-2.218 14.091-9.73 19.337-16.915 20.583-28.192 10.237-52.42 7.63-51.498-11.684 4.137-16.732 6.977-26.707 14.372-2.191 1.626-6.168 3.667-8.703 4.67-4.242 1.677-10.163-.797-12.471-1.916-.518-.266-1.338.232-1.541.779Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='m156.679 118.534-8.794 18.965c-.239.515-.029 1.677.477 1.916 8.155 3.722 11.617 7.744 12.976 9.222a510.414 510.414 0 0 1 17.796 20.405c4.462-2.218 14.09-9.73 19.336-16.915 20.584-28.192 10.237-52.42 7.631-51.498-11.684 4.137-16.732 6.977-26.707 14.372-2.191 1.626-6.169 3.667-8.703 4.67-4.243 1.677-10.163-.797-12.472-1.916-.517-.266-1.337.232-1.54.779Z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.04}
|
||||
/>
|
||||
</G>
|
||||
<Path
|
||||
d='M88.124 49.27c.121 1.962-.046 8.863 0 9.51.503 8.58 19.505 32.628 21.348 34.443 4.44 4.374 13.955 10.01 19.315 13.174 11.148 6.577 15.831 7.162 27.899 12.137l-8.794 18.965c-18.278-6.599-26.266-11.449-35.804-17.916-3.369-2.285-10.144-7.076-12.876-9.821-11.208-11.257-16.103-32.335-20.746-42.395-2.265-4.91-3.538-5.16-5.007-7.186-1.908-2.635-2.027-3.473-3.577-5.749-2.53-3.715-7.48-6.64-9.062-9.87a.413.413 0 0 1 .303-.584.409.409 0 0 1 .246.035c2.974 1.459 5.177 2.994 8.396 4.551.544-1.406-1.192-4.072-2.862-6.707-1.561-2.467-4.65-10.898-3.457-12.096.589-.591 2.385 1.97 3.219 3.473 3.1 5.51 4.65 7.066 4.65 7.066s-6.372-11.286-5.962-12.215c.954-2.156 5.228 4.04 8.585 9.102 1.907 2.874 3.1 3.592 3.1 3.592s-1.073-8.742-1.789-12.814c-.524-2.987 1.26-2.256 2.504 1.078.716 1.916 1.05 3.399 2.146 6.706a45.414 45.414 0 0 0 1.908 4.79c1.123 2.506 1.907 3.354 2.742 4.672.253-2.35.358-3.234 1.43-5.51 1.136-2.395 3.816-5.508 2.624-.718-.873 3.473-.594 8.462-.48 10.288ZM168.43 109.482c-1.028-.558-2.291-1.152-3.338-1.677-2.17-1.087-4.037-2.079-5.63-3.916a63.152 63.152 0 0 1-8.675-12.951c-1.023-2.031-1.946-4.154-2.251-6.41-.305-2.256.069-4.683 1.431-6.498 2.384-3.178 7.945-4.103 10.589-3.28 2.948.918 6.815 4.823 9.3 8.145 3.577 4.776 5.723 8.297 8.346 13.653.238.479 1.206 4.852 1.321 5.065 2.971 5.474 6.786 7.39 6.786 7.39l2.442-.958a6.171 6.171 0 0 1 3.494-.309 6.191 6.191 0 0 1 3.102 1.645 7.433 7.433 0 0 1 1.335 1.651c2.862 5.509 2.888 11.736-.954 15.569-3.841 3.832-7.656 5.37-12.995 4.431-2.781-.479-5.723-1.677-8.449-3.248-3.701-2.156-3.963-7.092-.715-9.873.019.007-2.394-6.951-5.139-8.429Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M171.203 112.682c5.392-2.506 6.796-5.691 7.123-6.661a.443.443 0 0 0-.119-.463l-.015-.012a.434.434 0 0 0-.368-.109.436.436 0 0 0-.271.157 9.81 9.81 0 0 1-2.351 2.058 9.203 9.203 0 0 1-5.287 1.756 8.988 8.988 0 0 1-2.079-.24c.208.108.415.216.608.321.985.534 1.939 1.801 2.759 3.193Z'
|
||||
fill='#CC8F00'
|
||||
/>
|
||||
<Path
|
||||
d='M166.399 99.609a6.721 6.721 0 0 0 3.851-3.26c.214-.407-.403-.772-.618-.362a6 6 0 0 1-3.429 2.942c-.434.146-.238.84.191.692l.005-.012ZM157.373 79.984c-1.257 4.908-1.478 9.998-6.247 12.873-3.367-2.499-4.905-10.484-2.623-14.633 1.33-2.41 5.67-5.202 9.023-6.268 1.094-.348 5.808 2.251 5.761 2.675-.353 3.236-3.842 6.297-5.485 9.102l-.429-3.749Z'
|
||||
fill='#6F370B'
|
||||
/>
|
||||
<Path
|
||||
d='M174.17 90.298c-.208-1.109.839-2.076.93-3.202.117-1.452-1.317-2.493-2.576-3.22a.844.844 0 0 0-.543-.162c-.315.055-.456.424-.511.74a5.848 5.848 0 0 0 .878 4.184l1.822 1.66Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M173.297 86.708a.683.683 0 0 1 .217-.853c.381-.256.024-.879-.36-.62a1.422 1.422 0 0 0-.477 1.837c.207.412.825.048.617-.364h.003ZM83.943 44.688c-1.771 1.823-2.68 4.508-3.004 6.994-.239 1.917.513 4.537 2.244 5.596.393.24.753-.381.36-.62-1.75-1.071-2.146-3.692-1.796-5.529.396-2.127 1.173-4.362 2.702-5.933.322-.33-.181-.838-.506-.508ZM75.373 63.565c1.639 1.164 4.343 1.368 5.876-.139.329-.323-.176-.83-.506-.508-1.318 1.296-3.631 1.004-5.007.027-.377-.269-.735.354-.36.62h-.003ZM162.35 91.544c.488.82.853 1.708 1.082 2.635.122.5.122 1.025.239 1.52.005.17.052.334.136.48.617.795 1.819-.213 2.212-.748.272-.373-.348-.733-.617-.364-.165.226-.592.736-.882.614-.201-.084-.148-.192-.179-.48a9.881 9.881 0 0 0-1.369-4.019.356.356 0 0 0-.646.094.36.36 0 0 0 .028.268h-.004ZM164.615 85.71c-1.073 0-1.076 1.676 0 1.676 1.075 0 1.078-1.677 0-1.677ZM157.759 90.44c-1.073 0-1.075 1.676 0 1.676 1.076 0 1.078-1.676 0-1.676Z'
|
||||
fill='#6F370B'
|
||||
/>
|
||||
<Path
|
||||
d='M35.265 117.963H11.052a3.359 3.359 0 0 0-2.392.983 3.39 3.39 0 0 0-.998 2.392v15.423a3.39 3.39 0 0 0 2.097 3.122c.41.169.85.255 1.293.253h3.574v5.774l5.36-5.774h15.27a3.359 3.359 0 0 0 2.393-.983 3.39 3.39 0 0 0 .998-2.392v-15.423a3.392 3.392 0 0 0-.995-2.389 3.376 3.376 0 0 0-2.387-.986Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M19.986 140.136h15.27a3.359 3.359 0 0 0 2.393-.983 3.39 3.39 0 0 0 .998-2.392v-9.363s-1.066 8.658-1.258 9.421c-.192.762-.572 1.902-2.373 2.091-1.8.189-15.03 1.226-15.03 1.226Z'
|
||||
fill='#CC8F00'
|
||||
/>
|
||||
<Path
|
||||
d='M14.889 126.845a2.179 2.179 0 0 1 2.015 1.349 2.191 2.191 0 0 1-.473 2.383 2.182 2.182 0 0 1-2.377.474 2.184 2.184 0 0 1-1.347-2.02 2.186 2.186 0 0 1 1.346-2.021c.265-.109.55-.166.836-.165ZM23.159 126.845a2.179 2.179 0 0 1 2.015 1.349 2.191 2.191 0 0 1-.473 2.383 2.182 2.182 0 0 1-2.377.474 2.184 2.184 0 0 1-1.346-2.02 2.188 2.188 0 0 1 1.346-2.021c.265-.109.548-.166.835-.165ZM31.42 126.845a2.187 2.187 0 0 1 .43 4.33 2.185 2.185 0 0 1-1.971-3.69 2.18 2.18 0 0 1 1.541-.64Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M10.175 124.421a6.86 6.86 0 0 1 3.273-4.143.24.24 0 0 0 .046-.395.24.24 0 0 0-.143-.055c-1.527-.092-4.608.235-3.642 4.57a.24.24 0 0 0 .224.195.245.245 0 0 0 .15-.044.247.247 0 0 0 .092-.128Z'
|
||||
fill='#FFD470'
|
||||
/>
|
||||
<Path
|
||||
d='M54.952 138.309v32.874c0 2.453 1.759 4.498 3.87 4.498h46.357c2.11 0 3.869-2.045 3.869-4.498v-32.874H54.952Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M109.048 133.764c0-2.479-1.761-4.545-3.874-4.545H58.826c-2.113 0-3.874 2.066-3.874 4.545v4.545h54.096v-4.545Z'
|
||||
fill='#CC8F00'
|
||||
/>
|
||||
<Path
|
||||
d='M66.737 130.716c3.453 0 6.247 1.147 6.247 2.621 0 1.475-2.794 2.621-6.246 2.621-3.453 0-6.247-1.146-6.247-2.621 0-1.392 2.794-2.621 6.246-2.621ZM97.26 130.716c3.452 0 6.246 1.147 6.246 2.621 0 1.475-2.794 2.621-6.246 2.621-3.452 0-6.247-1.146-6.247-2.621 0-1.392 2.795-2.621 6.247-2.621Z'
|
||||
fill='#090A0B'
|
||||
/>
|
||||
<Path
|
||||
d='M82.031 114.404c-10.43 0-18.965 8.523-18.965 19.002 0 .631 1.343 1.212 3.114 1.212v-1.144c.632-8.838 7.444-15.913 15.851-15.913 8.408 0 15.22 7.007 15.79 15.908v1.149c1.77 0 3.112-.518 3.112-1.149.063-10.542-8.47-19.065-18.902-19.065Z'
|
||||
fill='#DDDFE4'
|
||||
/>
|
||||
<Path
|
||||
d='M97.89 133.456c0-9.136-7.566-16.022-15.953-16.022s-16.14 6.886-15.757 17.184c1.765 0 3.334-.523 3.334-1.162 0-5.808 4.793-12.702 12.486-12.702 7.693 0 12.485 6.894 12.485 12.702 0 .639 1.577 1.162 3.406 1.162v-1.162Z'
|
||||
fill='#BABEC9'
|
||||
/>
|
||||
<Path
|
||||
d='m86.807 167.823-1.972-12.86c1.15-.901 1.972-2.294 1.972-3.85 0-2.622-2.137-4.833-4.767-4.833-2.63 0-4.767 2.129-4.767 4.833 0 1.556.74 3.031 1.973 3.85l-1.973 12.86h9.534Z'
|
||||
fill='#090A0B'
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default SvgComponent;
|
||||
125
app/components/illustrations/join_public_channel.tsx
Normal file
125
app/components/illustrations/join_public_channel.tsx
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import * as React from 'react';
|
||||
import Svg, {
|
||||
Path,
|
||||
Mask,
|
||||
G,
|
||||
EMaskUnits,
|
||||
} from 'react-native-svg';
|
||||
|
||||
type Props = {
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
function SvgComponent({theme}: Props) {
|
||||
return (
|
||||
<Svg
|
||||
width={200}
|
||||
height={201}
|
||||
fill='none'
|
||||
viewBox='0 0 210 170'
|
||||
>
|
||||
<Path
|
||||
d='M20.215 68.747h41.93a5.84 5.84 0 0 1 4.143 1.704 5.864 5.864 0 0 1 1.727 4.14v26.71a5.879 5.879 0 0 1-1.727 4.141 5.842 5.842 0 0 1-4.144 1.704h-6.188v9.998l-9.281-9.998H20.23a5.857 5.857 0 0 1-4.143-1.704 5.871 5.871 0 0 1-1.728-4.141v-26.71a5.871 5.871 0 0 1 1.722-4.135 5.844 5.844 0 0 1 4.134-1.709Z'
|
||||
fill={theme.buttonBg}
|
||||
/>
|
||||
<Path
|
||||
d='M46.675 107.146H20.23a5.857 5.857 0 0 1-4.143-1.704 5.871 5.871 0 0 1-1.728-4.141V85.086s1.846 14.994 2.178 16.314c.332 1.32.99 3.295 4.109 3.622 3.119.328 26.029 2.124 26.029 2.124Z'
|
||||
fill='#000'
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M55.501 84.128a3.77 3.77 0 0 0-3.49 2.337 3.795 3.795 0 0 0 .82 4.126 3.774 3.774 0 0 0 6.447-2.677 3.787 3.787 0 0 0-2.33-3.499 3.764 3.764 0 0 0-1.447-.287ZM41.18 84.128a3.77 3.77 0 0 0-3.49 2.337 3.794 3.794 0 0 0 .819 4.126 3.775 3.775 0 0 0 4.116.82 3.78 3.78 0 0 0 2.331-3.497 3.79 3.79 0 0 0-1.104-2.678 3.772 3.772 0 0 0-2.673-1.108ZM26.873 84.128a3.77 3.77 0 0 0-3.493 2.334 3.793 3.793 0 0 0 .816 4.127 3.774 3.774 0 0 0 6.45-2.675 3.787 3.787 0 0 0-2.328-3.498 3.764 3.764 0 0 0-1.445-.288Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M63.664 79.93a11.918 11.918 0 0 0-5.668-7.174.411.411 0 0 1 .168-.779c2.644-.159 7.98.407 6.307 7.914a.417.417 0 0 1-.807.04Z'
|
||||
fill='#fff'
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M207.944 110.447c0 36.185-29.205 65.518-65.232 65.518-36.026 0-65.231-29.333-65.231-65.518 0-36.184 29.205-65.518 65.231-65.518 36.027 0 65.232 29.334 65.232 65.518Zm-.637 0c0 35.832-28.92 64.879-64.595 64.879-35.674 0-64.595-29.047-64.595-64.879 0-35.832 28.921-64.879 64.595-64.879 35.675 0 64.595 29.047 64.595 64.879Z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M142.712 175.326c35.675 0 64.595-29.047 64.595-64.879 0-35.832-28.92-64.879-64.595-64.879s-64.595 29.047-64.595 64.879c0 35.832 28.92 64.879 64.595 64.879Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M142.712 175.326c35.675 0 64.595-29.047 64.595-64.879 0-35.832-28.92-64.879-64.595-64.879s-64.595 29.047-64.595 64.879c0 35.832 28.92 64.879 64.595 64.879Z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M155.792 71.637c2.437-.51 6.786-.958 9.91.984 2.029 1.263 3.191 3.507 4.631 5.416 1.631 2.156 3.689 3.97 5.408 6.063 5.246 6.395 6.965 15.552 4.378 23.427-.823 2.499-2.039 4.863-2.694 7.409-.83 3.229-.716 6.611-.976 9.933-.694 9.229-4.142 17.993-7.549 26.587-1.023 2.58-2.087 5.226-3.98 7.248-3.074 3.282-8.243 4.369-12.369 2.604-2.995-1.284-5.377-3.873-8.52-4.731-1.497-.407-3.073-.393-4.618-.532-7.869-.718-15.183-5.787-18.628-12.915-3.446-7.128-2.891-16.048 1.411-22.69 1.431-2.213 3.234-4.16 5.008-6.093l9.082-9.821c2.301-2.486 4.677-5.104 5.602-8.371.679-2.395.515-4.946.715-7.425.384-4.678 2.194-9.342 5.539-12.614 3.346-3.272 5.487-4.026 7.65-4.479Z'
|
||||
fill='#6F370B'
|
||||
/>
|
||||
<Mask
|
||||
id='a'
|
||||
maskUnits={'userSpaceOnUse' as EMaskUnits.USER_SPACE_ON_USE}
|
||||
x={76}
|
||||
y={43}
|
||||
width={134}
|
||||
height={135}
|
||||
>
|
||||
<Path
|
||||
d='M142.712 176.326c36.231 0 65.595-29.499 65.595-65.879 0-36.38-29.364-65.879-65.595-65.879-36.231 0-65.595 29.5-65.595 65.879 0 36.38 29.364 65.879 65.595 65.879Z'
|
||||
fill='#FFFFFF'
|
||||
/>
|
||||
</Mask>
|
||||
<G mask='url(#a)'>
|
||||
<Path
|
||||
d='m156.679 118.534-8.794 18.965c-.238.515-.029 1.677.477 1.916 8.155 3.722 11.617 7.744 12.977 9.222a511.194 511.194 0 0 1 17.795 20.405c4.462-2.218 14.091-9.73 19.337-16.915 20.583-28.192 10.237-52.42 7.63-51.498-11.684 4.137-16.732 6.977-26.707 14.372-2.191 1.626-6.168 3.667-8.703 4.67-4.242 1.677-10.163-.797-12.471-1.916-.518-.266-1.338.232-1.541.779Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='m156.679 118.534-8.794 18.965c-.239.515-.029 1.677.477 1.916 8.155 3.722 11.617 7.744 12.976 9.222a510.414 510.414 0 0 1 17.796 20.405c4.462-2.218 14.09-9.73 19.336-16.915 20.584-28.192 10.237-52.42 7.631-51.498-11.684 4.137-16.732 6.977-26.707 14.372-2.191 1.626-6.169 3.667-8.703 4.67-4.243 1.677-10.163-.797-12.472-1.916-.517-.266-1.337.232-1.54.779Z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.04}
|
||||
/>
|
||||
</G>
|
||||
<Path
|
||||
d='M88.124 49.27c.121 1.962-.046 8.863 0 9.51.503 8.58 19.505 32.628 21.348 34.443 4.44 4.374 13.955 10.01 19.315 13.174 11.148 6.577 15.831 7.162 27.899 12.137l-8.794 18.965c-18.278-6.599-26.266-11.449-35.804-17.916-3.369-2.285-10.144-7.076-12.876-9.821-11.208-11.257-16.103-32.335-20.746-42.395-2.265-4.91-3.538-5.16-5.007-7.186-1.908-2.635-2.027-3.473-3.577-5.749-2.53-3.715-7.48-6.64-9.062-9.87a.413.413 0 0 1 .303-.584.409.409 0 0 1 .246.035c2.974 1.459 5.177 2.994 8.396 4.551.544-1.406-1.192-4.072-2.862-6.707-1.561-2.467-4.65-10.898-3.457-12.096.589-.591 2.385 1.97 3.219 3.473 3.1 5.51 4.65 7.066 4.65 7.066s-6.372-11.286-5.962-12.215c.954-2.156 5.228 4.04 8.585 9.102 1.907 2.874 3.1 3.592 3.1 3.592s-1.073-8.742-1.789-12.814c-.524-2.987 1.26-2.256 2.504 1.078.716 1.916 1.05 3.399 2.146 6.706a45.414 45.414 0 0 0 1.908 4.79c1.123 2.506 1.907 3.354 2.742 4.672.253-2.35.358-3.234 1.43-5.51 1.136-2.395 3.816-5.508 2.624-.718-.873 3.473-.594 8.462-.48 10.288ZM168.43 109.482c-1.028-.558-2.291-1.152-3.338-1.677-2.17-1.087-4.037-2.079-5.63-3.916a63.152 63.152 0 0 1-8.675-12.951c-1.023-2.031-1.946-4.154-2.251-6.41-.305-2.256.069-4.683 1.431-6.498 2.384-3.178 7.945-4.103 10.589-3.28 2.948.918 6.815 4.823 9.3 8.145 3.577 4.776 5.723 8.297 8.346 13.653.238.479 1.206 4.852 1.321 5.065 2.971 5.474 6.786 7.39 6.786 7.39l2.442-.958a6.171 6.171 0 0 1 3.494-.309 6.191 6.191 0 0 1 3.102 1.645 7.433 7.433 0 0 1 1.335 1.651c2.862 5.509 2.888 11.736-.954 15.569-3.841 3.832-7.656 5.37-12.995 4.431-2.781-.479-5.723-1.677-8.449-3.248-3.701-2.156-3.963-7.092-.715-9.873.019.007-2.394-6.951-5.139-8.429Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M171.203 112.682c5.392-2.506 6.796-5.691 7.123-6.661a.443.443 0 0 0-.119-.463l-.015-.012a.434.434 0 0 0-.368-.109.436.436 0 0 0-.271.157 9.81 9.81 0 0 1-2.351 2.058 9.203 9.203 0 0 1-5.287 1.756 8.988 8.988 0 0 1-2.079-.24c.208.108.415.216.608.321.985.534 1.939 1.801 2.759 3.193Z'
|
||||
fill='#CC8F00'
|
||||
/>
|
||||
<Path
|
||||
d='M166.399 99.609a6.721 6.721 0 0 0 3.851-3.26c.214-.407-.403-.772-.618-.362a6 6 0 0 1-3.429 2.942c-.434.146-.238.84.191.692l.005-.012ZM157.373 79.984c-1.257 4.908-1.478 9.998-6.247 12.873-3.367-2.499-4.905-10.484-2.623-14.633 1.33-2.41 5.67-5.202 9.023-6.268 1.094-.348 5.808 2.251 5.761 2.675-.353 3.236-3.842 6.297-5.485 9.102l-.429-3.749Z'
|
||||
fill='#6F370B'
|
||||
/>
|
||||
<Path
|
||||
d='M174.17 90.298c-.208-1.109.839-2.076.93-3.202.117-1.452-1.317-2.493-2.576-3.22a.844.844 0 0 0-.543-.162c-.315.055-.456.424-.511.74a5.848 5.848 0 0 0 .878 4.184l1.822 1.66Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M173.297 86.708a.683.683 0 0 1 .217-.853c.381-.256.024-.879-.36-.62a1.422 1.422 0 0 0-.477 1.837c.207.412.825.048.617-.364h.003ZM83.943 44.688c-1.771 1.823-2.68 4.508-3.004 6.994-.239 1.917.513 4.537 2.244 5.596.393.24.753-.381.36-.62-1.75-1.071-2.146-3.692-1.796-5.529.396-2.127 1.173-4.362 2.702-5.933.322-.33-.181-.838-.506-.508ZM75.373 63.565c1.639 1.164 4.343 1.368 5.876-.139.329-.323-.176-.83-.506-.508-1.318 1.296-3.631 1.004-5.007.027-.377-.269-.735.354-.36.62h-.003ZM162.35 91.544c.488.82.853 1.708 1.082 2.635.122.5.122 1.025.239 1.52.005.17.052.334.136.48.617.795 1.819-.213 2.212-.748.272-.373-.348-.733-.617-.364-.165.226-.592.736-.882.614-.201-.084-.148-.192-.179-.48a9.881 9.881 0 0 0-1.369-4.019.356.356 0 0 0-.646.094.36.36 0 0 0 .028.268h-.004ZM164.615 85.71c-1.073 0-1.076 1.676 0 1.676 1.075 0 1.078-1.677 0-1.677ZM157.759 90.44c-1.073 0-1.075 1.676 0 1.676 1.076 0 1.078-1.676 0-1.676Z'
|
||||
fill='#6F370B'
|
||||
/>
|
||||
<Path
|
||||
d='M35.265 117.963H11.052a3.359 3.359 0 0 0-2.392.983 3.39 3.39 0 0 0-.998 2.392v15.423a3.39 3.39 0 0 0 2.097 3.122c.41.169.85.255 1.293.253h3.574v5.774l5.36-5.774h15.27a3.359 3.359 0 0 0 2.393-.983 3.39 3.39 0 0 0 .998-2.392v-15.423a3.392 3.392 0 0 0-.995-2.389 3.376 3.376 0 0 0-2.387-.986Z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M19.986 140.136h15.27a3.359 3.359 0 0 0 2.393-.983 3.39 3.39 0 0 0 .998-2.392v-9.363s-1.066 8.658-1.258 9.421c-.192.762-.572 1.902-2.373 2.091-1.8.189-15.03 1.226-15.03 1.226Z'
|
||||
fill='#CC8F00'
|
||||
/>
|
||||
<Path
|
||||
d='M14.889 126.845a2.179 2.179 0 0 1 2.015 1.349 2.191 2.191 0 0 1-.473 2.383 2.182 2.182 0 0 1-2.377.474 2.184 2.184 0 0 1-1.347-2.02 2.186 2.186 0 0 1 1.346-2.021c.265-.109.55-.166.836-.165ZM23.159 126.845a2.179 2.179 0 0 1 2.015 1.349 2.191 2.191 0 0 1-.473 2.383 2.182 2.182 0 0 1-2.377.474 2.184 2.184 0 0 1-1.346-2.02 2.188 2.188 0 0 1 1.346-2.021c.265-.109.548-.166.835-.165ZM31.42 126.845a2.187 2.187 0 0 1 .43 4.33 2.185 2.185 0 0 1-1.971-3.69 2.18 2.18 0 0 1 1.541-.64Z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M10.175 124.421a6.86 6.86 0 0 1 3.273-4.143.24.24 0 0 0 .046-.395.24.24 0 0 0-.143-.055c-1.527-.092-4.608.235-3.642 4.57a.24.24 0 0 0 .224.195.245.245 0 0 0 .15-.044.247.247 0 0 0 .092-.128Z'
|
||||
fill='#FFD470'
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default SvgComponent;
|
||||
56
app/components/illustrations/message_not_viewable.tsx
Normal file
56
app/components/illustrations/message_not_viewable.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import * as React from 'react';
|
||||
import Svg, {Path, Ellipse} from 'react-native-svg';
|
||||
|
||||
type Props = {
|
||||
theme: Theme;
|
||||
}
|
||||
|
||||
function SvgComponent({theme}: Props) {
|
||||
return (
|
||||
<Svg
|
||||
width={180}
|
||||
height={157}
|
||||
viewBox='0 0 180 157'
|
||||
fill='none'
|
||||
>
|
||||
<Path
|
||||
d='M127.838 40.436h-75.65a10.577 10.577 0 00-7.475 3.06 10.533 10.533 0 00-3.117 7.44v47.977a10.513 10.513 0 003.117 7.439 10.576 10.576 0 007.475 3.061h11.165v17.959l16.746-17.959h47.712a10.573 10.573 0 007.476-3.061 10.516 10.516 0 003.117-7.439V50.937a10.521 10.521 0 00-3.108-7.43 10.567 10.567 0 00-7.458-3.07z'
|
||||
fill='#1C58D9'
|
||||
/>
|
||||
<Path
|
||||
d='M80.1 109.413h47.712a10.568 10.568 0 007.475-3.061 10.523 10.523 0 003.117-7.439V69.787s-3.331 26.935-3.929 29.306c-.599 2.371-1.787 5.918-7.414 6.506-5.626.588-46.961 3.815-46.961 3.815z'
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M64.174 68.066c1.348 0 2.665.399 3.786 1.146a6.787 6.787 0 011.033 10.463 6.82 6.82 0 01-7.427 1.474 6.812 6.812 0 01-3.058-2.504 6.79 6.79 0 01-.632-6.382 6.792 6.792 0 013.689-3.682 6.82 6.82 0 012.61-.515zM90.014 68.066c1.348 0 2.665.399 3.786 1.146a6.804 6.804 0 012.51 3.052 6.787 6.787 0 01-1.477 7.411 6.819 6.819 0 01-7.427 1.474 6.812 6.812 0 01-3.058-2.504 6.79 6.79 0 01-.632-6.382 6.79 6.79 0 013.689-3.682 6.818 6.818 0 012.609-.515zM115.825 68.066a6.825 6.825 0 013.788 1.142 6.802 6.802 0 012.906 6.98 6.802 6.802 0 01-5.352 5.348 6.829 6.829 0 01-6.999-2.89 6.792 6.792 0 01-.633-6.381 6.781 6.781 0 013.683-3.681 6.82 6.82 0 012.607-.518z'
|
||||
fill={theme.centerChannelBg}
|
||||
/>
|
||||
<Path
|
||||
d='M49.447 60.526a21.376 21.376 0 013.823-7.464 21.424 21.424 0 016.403-5.424.74.74 0 00-.304-1.4c-4.769-.285-14.397.731-11.378 14.217a.748.748 0 00.7.606.752.752 0 00.755-.535z'
|
||||
fill={theme.centerChannelBg}
|
||||
fillOpacity={0.16}
|
||||
/>
|
||||
<Path
|
||||
d='M114.364 62.33c-2.475 0-3.597-1.785-2.492-3.966L131.88 19.06c1.133-2.175 2.917-2.175 4.028 0l20.002 39.303c1.133 2.175 0 3.965-2.493 3.965h-39.053z'
|
||||
fill='#FFBC1F'
|
||||
/>
|
||||
<Path
|
||||
d='M130.753 33.597l2.056 13.816a1.09 1.09 0 001.826.718 1.09 1.09 0 00.344-.718l2.056-13.816c.374-5.387-6.662-5.387-6.282 0zM133.891 49.912a3.148 3.148 0 013.083 3.767 3.153 3.153 0 01-2.476 2.472 3.149 3.149 0 11-.607-6.24z'
|
||||
fill='#2D3039'
|
||||
/>
|
||||
<Ellipse
|
||||
cx={90.5}
|
||||
cy={131}
|
||||
rx={62.5}
|
||||
ry={3}
|
||||
fill={theme.centerChannelColor}
|
||||
fillOpacity={0.06}
|
||||
/>
|
||||
</Svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default SvgComponent;
|
||||
|
|
@ -37,6 +37,7 @@ import type {
|
|||
type MarkdownProps = {
|
||||
autolinkedUrlSchemes?: string[];
|
||||
baseTextStyle: StyleProp<TextStyle>;
|
||||
baseParagraphStyle?: StyleProp<TextStyle>;
|
||||
blockStyles?: MarkdownBlockStyles;
|
||||
channelId?: string;
|
||||
channelMentions?: ChannelMentions;
|
||||
|
|
@ -131,7 +132,7 @@ const Markdown = ({
|
|||
enableInlineLatex, enableLatex,
|
||||
imagesMetadata, isEdited, isReplyPost, isSearchResult, layoutHeight, layoutWidth,
|
||||
location, mentionKeys, minimumHashtagLength = 3, onPostPress, postId, searchPatterns,
|
||||
textStyles = {}, theme, value = '',
|
||||
textStyles = {}, theme, value = '', baseParagraphStyle,
|
||||
}: MarkdownProps) => {
|
||||
const style = getStyleSheet(theme);
|
||||
|
||||
|
|
@ -419,7 +420,7 @@ const Markdown = ({
|
|||
|
||||
return (
|
||||
<View style={blockStyle}>
|
||||
<Text>
|
||||
<Text style={baseParagraphStyle}>
|
||||
{children}
|
||||
</Text>
|
||||
</View>
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ export const queryTeamsById = (database: Database, teamIds: string[]) => {
|
|||
return database.get<TeamModel>(TEAM).query(Q.where('id', Q.oneOf(teamIds)));
|
||||
};
|
||||
|
||||
export const queryTeamByName = async (database: Database, teamName: string) => {
|
||||
export const queryTeamByName = (database: Database, teamName: string) => {
|
||||
return database.get<TeamModel>(TEAM).query(Q.where('name', teamName));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,21 +7,38 @@ import {of as of$} from 'rxjs';
|
|||
import {switchMap} from 'rxjs/operators';
|
||||
|
||||
import {observePost} from '@queries/servers/post';
|
||||
import {observeCurrentTeamId, observeCurrentUserId} from '@queries/servers/system';
|
||||
import {queryMyTeamsByIds, queryTeamByName} from '@queries/servers/team';
|
||||
import {observeIsCRTEnabled} from '@queries/servers/thread';
|
||||
import {WithDatabaseArgs} from '@typings/database/database';
|
||||
import PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
import Permalink from './permalink';
|
||||
|
||||
type OwnProps = {postId: PostModel['id']} & WithDatabaseArgs;
|
||||
type OwnProps = {
|
||||
postId: PostModel['id'];
|
||||
teamName?: string;
|
||||
} & WithDatabaseArgs;
|
||||
|
||||
const enhance = withObservables([], ({database, postId}: OwnProps) => {
|
||||
const enhance = withObservables([], ({database, postId, teamName}: OwnProps) => {
|
||||
const post = observePost(database, postId);
|
||||
const team = teamName ? queryTeamByName(database, teamName).observe().pipe(
|
||||
switchMap((ts) => {
|
||||
const t = ts[0];
|
||||
return t ? t.observe() : of$(undefined);
|
||||
}),
|
||||
) : of$(undefined);
|
||||
|
||||
return {
|
||||
channel: post.pipe(
|
||||
switchMap((p) => (p ? p.channel.observe() : of$(undefined))),
|
||||
),
|
||||
isTeamMember: team.pipe(
|
||||
switchMap((t) => (t ? queryMyTeamsByIds(database, [t.id]).observe() : of$(undefined))),
|
||||
switchMap((ms) => of$(Boolean(ms?.[0]))),
|
||||
),
|
||||
currentTeamId: observeCurrentTeamId(database),
|
||||
currentUserId: observeCurrentUserId(database),
|
||||
isCRTEnabled: observeIsCRTEnabled(database),
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,12 +2,13 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {BackHandler, Text, TouchableOpacity, View} from 'react-native';
|
||||
import {Alert, BackHandler, Text, TouchableOpacity, View} from 'react-native';
|
||||
import Animated from 'react-native-reanimated';
|
||||
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import {switchToChannelById} from '@actions/remote/channel';
|
||||
import {fetchPostsAround} from '@actions/remote/post';
|
||||
import {fetchChannelById, joinChannel, switchToChannelById} from '@actions/remote/channel';
|
||||
import {fetchPostById, fetchPostsAround} from '@actions/remote/post';
|
||||
import {addUserToTeam, fetchTeamByName, removeUserFromTeam} from '@actions/remote/team';
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import Loading from '@components/loading';
|
||||
|
|
@ -15,7 +16,9 @@ import PostList from '@components/post_list';
|
|||
import {Screens} from '@constants';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import DatabaseManager from '@database/manager';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {getChannelById, getMyChannel} from '@queries/servers/channel';
|
||||
import {dismissModal} from '@screens/navigation';
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
|
||||
|
|
@ -24,11 +27,17 @@ import {preventDoubleTap} from '@utils/tap';
|
|||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
import PermalinkError from './permalink_error';
|
||||
|
||||
import type ChannelModel from '@typings/database/models/servers/channel';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
type Props = {
|
||||
channel?: ChannelModel;
|
||||
teamName?: string;
|
||||
isTeamMember?: boolean;
|
||||
currentUserId: string;
|
||||
currentTeamId: string;
|
||||
isCRTEnabled: boolean;
|
||||
postId: PostModel['id'];
|
||||
}
|
||||
|
|
@ -48,6 +57,8 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
flex: 1,
|
||||
margin: 10,
|
||||
opacity: 1,
|
||||
borderWidth: 1,
|
||||
borderColor: changeOpacity(theme.centerChannelColor, 0.16),
|
||||
},
|
||||
header: {
|
||||
alignItems: 'center',
|
||||
|
|
@ -102,23 +113,18 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
|||
fontWeight: '600',
|
||||
textAlignVertical: 'center',
|
||||
},
|
||||
errorContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: 15,
|
||||
},
|
||||
errorText: {
|
||||
color: changeOpacity(theme.centerChannelColor, 0.4),
|
||||
fontSize: 15,
|
||||
},
|
||||
archiveIcon: {
|
||||
color: theme.centerChannelColor,
|
||||
fontSize: 16,
|
||||
paddingRight: 20,
|
||||
},
|
||||
}));
|
||||
}),
|
||||
);
|
||||
|
||||
function Permalink({channel, isCRTEnabled, postId}: Props) {
|
||||
function Permalink({
|
||||
channel,
|
||||
isCRTEnabled,
|
||||
postId,
|
||||
teamName,
|
||||
isTeamMember,
|
||||
currentUserId,
|
||||
currentTeamId,
|
||||
}: Props) {
|
||||
const [posts, setPosts] = useState<PostModel[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const theme = useTheme();
|
||||
|
|
@ -126,6 +132,8 @@ function Permalink({channel, isCRTEnabled, postId}: Props) {
|
|||
const insets = useSafeAreaInsets();
|
||||
const isTablet = useIsTablet();
|
||||
const style = getStyleSheet(theme);
|
||||
const [error, setError] = useState<PermalinkErrorType>();
|
||||
const [channelId, setChannelId] = useState(channel?.id);
|
||||
|
||||
const containerStyle = useMemo(() => {
|
||||
const marginTop = isTablet ? 60 : 20;
|
||||
|
|
@ -135,20 +143,113 @@ function Permalink({channel, isCRTEnabled, postId}: Props) {
|
|||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
if (channel?.id) {
|
||||
const data = await fetchPostsAround(serverUrl, channel.id, postId, 5, isCRTEnabled);
|
||||
if (channelId) {
|
||||
const data = await fetchPostsAround(serverUrl, channelId, postId, 5, isCRTEnabled);
|
||||
if (data.error) {
|
||||
setError({unreachable: true});
|
||||
}
|
||||
if (data?.posts) {
|
||||
setLoading(false);
|
||||
setPosts(data.posts);
|
||||
}
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const database = DatabaseManager.serverDatabases[serverUrl]?.database;
|
||||
if (!database) {
|
||||
setError({unreachable: true});
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// If a team is provided, try to join the team, but do not fail here, to take into account:
|
||||
// - Wrong team name
|
||||
// - DMs/GMs
|
||||
let joinedTeam: Team | undefined;
|
||||
if (teamName && !isTeamMember) {
|
||||
const fetchData = await fetchTeamByName(serverUrl, teamName, true);
|
||||
joinedTeam = fetchData.team;
|
||||
|
||||
if (joinedTeam) {
|
||||
const addData = await addUserToTeam(serverUrl, joinedTeam.id, currentUserId);
|
||||
if (addData.error) {
|
||||
joinedTeam = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const {post} = await fetchPostById(serverUrl, postId, true);
|
||||
if (!post) {
|
||||
if (joinedTeam) {
|
||||
removeUserFromTeam(serverUrl, joinedTeam.id, currentUserId);
|
||||
}
|
||||
setError({notExist: true});
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const myChannel = await getMyChannel(database, post.channel_id);
|
||||
if (myChannel) {
|
||||
const localChannel = await getChannelById(database, myChannel.id);
|
||||
|
||||
// Wrong team passed or DM/GM
|
||||
if (joinedTeam && localChannel?.teamId !== '' && localChannel?.teamId !== joinedTeam.id) {
|
||||
removeUserFromTeam(serverUrl, joinedTeam.id, currentUserId);
|
||||
joinedTeam = undefined;
|
||||
}
|
||||
|
||||
if (joinedTeam) {
|
||||
setError({
|
||||
joinedTeam: true,
|
||||
channelId: myChannel.id,
|
||||
channelName: localChannel?.displayName,
|
||||
privateTeam: !joinedTeam.allow_open_invite,
|
||||
teamName: joinedTeam.display_name,
|
||||
teamId: joinedTeam.id,
|
||||
});
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
setChannelId(post.channel_id);
|
||||
return;
|
||||
}
|
||||
|
||||
const {channel: fetchedChannel} = await fetchChannelById(serverUrl, post.channel_id);
|
||||
if (!fetchedChannel) {
|
||||
if (joinedTeam) {
|
||||
removeUserFromTeam(serverUrl, joinedTeam.id, currentUserId);
|
||||
}
|
||||
setError({notExist: true});
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrong team passed or DM/GM
|
||||
if (joinedTeam && fetchedChannel.team_id !== '' && fetchedChannel.team_id !== joinedTeam.id) {
|
||||
removeUserFromTeam(serverUrl, joinedTeam.id, currentUserId);
|
||||
joinedTeam = undefined;
|
||||
}
|
||||
|
||||
setError({
|
||||
privateChannel: fetchedChannel.type === 'P',
|
||||
joinedTeam: Boolean(joinedTeam),
|
||||
channelId: fetchedChannel.id,
|
||||
channelName: fetchedChannel.display_name,
|
||||
teamId: fetchedChannel.team_id || currentTeamId,
|
||||
teamName: joinedTeam?.display_name,
|
||||
privateTeam: joinedTeam && !joinedTeam.allow_open_invite,
|
||||
});
|
||||
setLoading(false);
|
||||
})();
|
||||
}, [channel?.id]);
|
||||
}, [channelId, teamName]);
|
||||
|
||||
const handleClose = useCallback(() => {
|
||||
if (error?.joinedTeam && error.teamId) {
|
||||
removeUserFromTeam(serverUrl, error.teamId, currentUserId);
|
||||
}
|
||||
dismissModal({componentId: Screens.PERMALINK});
|
||||
closePermalink();
|
||||
}, []);
|
||||
}, [error]);
|
||||
|
||||
useEffect(() => {
|
||||
const listener = BackHandler.addEventListener('hardwareBackPress', () => {
|
||||
|
|
@ -171,6 +272,71 @@ function Permalink({channel, isCRTEnabled, postId}: Props) {
|
|||
}
|
||||
}), []);
|
||||
|
||||
const handleJoin = useCallback(preventDoubleTap(async () => {
|
||||
if (error?.teamId && error.channelId) {
|
||||
const {error: joinError} = await joinChannel(serverUrl, currentUserId, error.teamId, error.channelId);
|
||||
if (joinError) {
|
||||
Alert.alert('Error joining the channel', 'There was an error trying to join the channel');
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
setError(undefined);
|
||||
setChannelId(error.channelId);
|
||||
}
|
||||
}), [error, serverUrl, currentUserId]);
|
||||
|
||||
let content;
|
||||
if (loading) {
|
||||
content = (
|
||||
<View style={style.loading}>
|
||||
<Loading
|
||||
color={theme.buttonBg}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
} else if (error) {
|
||||
content = (
|
||||
<PermalinkError
|
||||
error={error}
|
||||
handleClose={handleClose}
|
||||
handleJoin={handleJoin}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
content = (
|
||||
<>
|
||||
<View style={style.postList}>
|
||||
<PostList
|
||||
highlightedId={postId}
|
||||
posts={posts}
|
||||
location={Screens.PERMALINK}
|
||||
lastViewedAt={0}
|
||||
shouldShowJoinLeaveMessages={false}
|
||||
channelId={channel!.id}
|
||||
testID='permalink.post_list'
|
||||
nativeID={Screens.PERMALINK}
|
||||
highlightPinnedOrSaved={false}
|
||||
/>
|
||||
</View>
|
||||
<View style={style.footer}>
|
||||
<TouchableOpacity
|
||||
style={[buttonBackgroundStyle(theme, 'lg', 'primary'), {width: '100%'}]}
|
||||
onPress={handlePress}
|
||||
testID='permalink.jump_to_recent_messages.button'
|
||||
>
|
||||
<FormattedText
|
||||
testID='permalink.search.jump'
|
||||
id='mobile.search.jump'
|
||||
defaultMessage='Jump to recent messages'
|
||||
style={buttonTextStyle(theme, 'lg', 'primary')}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const showHeaderDivider = Boolean(channel?.displayName) && !error && !loading;
|
||||
return (
|
||||
<SafeAreaView
|
||||
style={containerStyle}
|
||||
|
|
@ -199,45 +365,12 @@ function Permalink({channel, isCRTEnabled, postId}: Props) {
|
|||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
{Boolean(channel?.displayName) &&
|
||||
<View style={style.divider}/>
|
||||
}
|
||||
{loading ? (
|
||||
<View style={style.loading}>
|
||||
<Loading
|
||||
color={theme.buttonBg}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<View style={style.postList}>
|
||||
<PostList
|
||||
highlightedId={postId}
|
||||
isCRTEnabled={isCRTEnabled}
|
||||
posts={posts}
|
||||
location={Screens.PERMALINK}
|
||||
lastViewedAt={0}
|
||||
shouldShowJoinLeaveMessages={false}
|
||||
channelId={channel!.id}
|
||||
testID='permalink.post_list'
|
||||
nativeID={Screens.PERMALINK}
|
||||
highlightPinnedOrSaved={false}
|
||||
/>
|
||||
{showHeaderDivider && (
|
||||
<View style={style.dividerContainer}>
|
||||
<View style={style.divider}/>
|
||||
</View>
|
||||
)}
|
||||
<View style={style.footer}>
|
||||
<TouchableOpacity
|
||||
style={[buttonBackgroundStyle(theme, 'lg', 'primary'), {width: '100%'}]}
|
||||
onPress={handlePress}
|
||||
testID='permalink.jump_to_recent_messages.button'
|
||||
>
|
||||
<FormattedText
|
||||
testID='permalink.search.jump'
|
||||
id='mobile.search.jump'
|
||||
defaultMessage='Jump to recent messages'
|
||||
style={buttonTextStyle(theme, 'lg', 'primary')}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
{content}
|
||||
</Animated.View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
|
|
|||
168
app/screens/permalink/permalink_error.tsx
Normal file
168
app/screens/permalink/permalink_error.tsx
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
import React from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Text, TouchableOpacity, View} from 'react-native';
|
||||
|
||||
import FormattedText from '@components/formatted_text';
|
||||
import JoinPrivateChannel from '@components/illustrations/join_private_channel';
|
||||
import JoinPublicChannel from '@components/illustrations/join_public_channel';
|
||||
import MessageNotViewable from '@components/illustrations/message_not_viewable';
|
||||
import Markdown from '@components/markdown';
|
||||
import {Screens} from '@constants';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
|
||||
import {getMarkdownBlockStyles, getMarkdownTextStyles} from '@utils/markdown';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
type Props = {
|
||||
error: PermalinkErrorType;
|
||||
handleClose: () => void;
|
||||
handleJoin: () => void;
|
||||
}
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
return {
|
||||
errorContainer: {
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginHorizontal: 36,
|
||||
flex: 1,
|
||||
},
|
||||
errorTitle: {
|
||||
color: theme.centerChannelColor,
|
||||
textAlign: 'center',
|
||||
...typography('Heading', 600, 'SemiBold'),
|
||||
marginTop: 8,
|
||||
marginBottom: 16,
|
||||
},
|
||||
errorText: {
|
||||
textAlign: 'center',
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 200, 'Regular'),
|
||||
},
|
||||
errorTextParagraph: {
|
||||
textAlign: 'center',
|
||||
},
|
||||
errorButtonContainer: {
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: changeOpacity(theme.centerChannelColor, 0.16),
|
||||
padding: 20,
|
||||
},
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
function PermalinkError({
|
||||
error,
|
||||
handleClose,
|
||||
handleJoin,
|
||||
}: Props) {
|
||||
const theme = useTheme();
|
||||
const style = getStyleSheet(theme);
|
||||
const intl = useIntl();
|
||||
|
||||
const buttonStylePrimary = buttonBackgroundStyle(theme, 'lg', 'primary');
|
||||
const buttonTextStylePrimary = buttonTextStyle(theme, 'lg', 'primary');
|
||||
|
||||
if (error.notExist || error.unreachable) {
|
||||
const title = intl.formatMessage({id: 'permalink.error.access.title', defaultMessage: 'Message not viewable'});
|
||||
const text = intl.formatMessage({id: 'permalink.error.access.text', defaultMessage: 'The message you are trying to view is in a channel you don’t have access to or has been deleted.'});
|
||||
return (
|
||||
<>
|
||||
<View style={style.errorContainer}>
|
||||
<MessageNotViewable theme={theme}/>
|
||||
<Text style={style.errorTitle}>{title}</Text>
|
||||
<Text style={style.errorText}>{text}</Text>
|
||||
</View>
|
||||
<View style={style.errorButtonContainer}>
|
||||
<TouchableOpacity
|
||||
style={buttonStylePrimary}
|
||||
onPress={handleClose}
|
||||
>
|
||||
<FormattedText
|
||||
testID='permalink.error.okay'
|
||||
id='permalink.error.okay'
|
||||
defaultMessage='Okay'
|
||||
style={buttonTextStylePrimary}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const buttonStyleTertiary = buttonBackgroundStyle(theme, 'lg', 'tertiary');
|
||||
const buttonTextStyleTertiary = buttonTextStyle(theme, 'lg', 'tertiary');
|
||||
|
||||
const isPrivate = error.privateChannel || error.privateTeam;
|
||||
let image;
|
||||
let title;
|
||||
let text;
|
||||
let button;
|
||||
if (isPrivate && error.joinedTeam) {
|
||||
image = (<JoinPrivateChannel theme={theme}/>);
|
||||
title = intl.formatMessage({id: 'permalink.error.private_channel_and_team.title', defaultMessage: 'Join private channel and team'});
|
||||
text = intl.formatMessage({id: 'permalink.error.private_channel_and_team.text', defaultMessage: 'The message you are trying to view is in a private channel in a team you are not a member of. You have access as an admin. Do you want to join **{channelName}** and the **{teamName}** team to view it?'}, {channelName: error.channelName, teamName: error.teamName});
|
||||
button = intl.formatMessage({id: 'permalink.error.private_channel_and_team.button', defaultMessage: 'Join channel and team'});
|
||||
} else if (isPrivate) {
|
||||
image = (<JoinPrivateChannel theme={theme}/>);
|
||||
title = intl.formatMessage({id: 'permalink.error.private_channel.title', defaultMessage: 'Join private channel'});
|
||||
text = intl.formatMessage({id: 'permalink.error.private_channel.text', defaultMessage: 'The message you are trying to view is in a private channel you have not been invited to, but you have access as an admin. Do you still want to join **{channelName}**?'}, {channelName: error.channelName});
|
||||
button = intl.formatMessage({id: 'permalink.error.private_channel.button', defaultMessage: 'Join channel'});
|
||||
} else if (error.joinedTeam) {
|
||||
image = (<JoinPublicChannel theme={theme}/>);
|
||||
title = intl.formatMessage({id: 'permalink.error.public_channel_and_team.title', defaultMessage: 'Join channel and team'});
|
||||
text = intl.formatMessage({id: 'permalink.error.public_channel_and_team.text', defaultMessage: 'The message you are trying to view is in a channel you don’t belong and a team you are not a member of. Do you want to join **{channelName}** and the **{teamName}** team to view it?'}, {channelName: error.channelName, teamName: error.teamName});
|
||||
button = intl.formatMessage({id: 'permalink.error.public_channel_and_team.button', defaultMessage: 'Join channel and team'});
|
||||
} else {
|
||||
image = (<JoinPublicChannel theme={theme}/>);
|
||||
title = intl.formatMessage({id: 'permalink.error.public_channel.title', defaultMessage: 'Join channel'});
|
||||
text = intl.formatMessage({id: 'permalink.error.public_channel.text', defaultMessage: 'The message you are trying to view is in a channel you don’t belong to. Do you want to join **{channelName}** to view it?'}, {channelName: error.channelName});
|
||||
button = intl.formatMessage({id: 'permalink.error.public_channel.button', defaultMessage: 'Join channel'});
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<View style={style.errorContainer}>
|
||||
{image}
|
||||
<Text style={style.errorTitle}>{title}</Text>
|
||||
<Markdown
|
||||
theme={theme}
|
||||
value={text}
|
||||
baseTextStyle={style.errorText}
|
||||
baseParagraphStyle={style.errorTextParagraph}
|
||||
disableAtMentions={true}
|
||||
disableAtChannelMentionHighlight={true}
|
||||
disableChannelLink={true}
|
||||
disableGallery={true}
|
||||
disableHashtags={true}
|
||||
textStyles={getMarkdownTextStyles(theme)}
|
||||
blockStyles={getMarkdownBlockStyles(theme)}
|
||||
location={Screens.PERMALINK}
|
||||
/>
|
||||
</View>
|
||||
<View style={style.errorButtonContainer}>
|
||||
<TouchableOpacity
|
||||
style={buttonStylePrimary}
|
||||
onPress={handleJoin}
|
||||
>
|
||||
<Text style={buttonTextStylePrimary}>{button}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[buttonStyleTertiary, {marginTop: 8}]}
|
||||
onPress={handleClose}
|
||||
>
|
||||
<FormattedText
|
||||
testID='permalink.error.cancel'
|
||||
id='permalink.error.cancel'
|
||||
defaultMessage='Cancel'
|
||||
style={buttonTextStyleTertiary}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default PermalinkError;
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
import {Keyboard, Platform} from 'react-native';
|
||||
import {OptionsModalPresentationStyle} from 'react-native-navigation';
|
||||
|
||||
import {Screens} from '@constants';
|
||||
import {dismissAllModals, showModalOverCurrentContext} from '@screens/navigation';
|
||||
import {changeOpacity} from '@utils/theme';
|
||||
|
||||
|
|
@ -15,7 +16,7 @@ export const displayPermalink = async (teamName: string, postId: string, openAsP
|
|||
await dismissAllModals();
|
||||
}
|
||||
|
||||
const screen = 'Permalink';
|
||||
const screen = Screens.PERMALINK;
|
||||
const passProps = {
|
||||
isPermalink: openAsPermalink,
|
||||
teamName,
|
||||
|
|
|
|||
|
|
@ -598,6 +598,22 @@
|
|||
"password_send.link.title": "Reset Link Sent",
|
||||
"password_send.reset": "Reset Your Password",
|
||||
"password_send.return": "Return to Log In",
|
||||
"permalink.error.access.text": "The message you are trying to view is in a channel you don’t have access to or has been deleted.",
|
||||
"permalink.error.access.title": "Message not viewable",
|
||||
"permalink.error.cancel": "Cancel",
|
||||
"permalink.error.okay": "Okay",
|
||||
"permalink.error.private_channel_and_team.button": "Join channel and team",
|
||||
"permalink.error.private_channel_and_team.text": "The message you are trying to view is in a private channel in a team you are not a member of. You have access as an admin. Do you want to join **{channelName}** and the **{teamName}** team to view it?",
|
||||
"permalink.error.private_channel_and_team.title": "Join private channel and team",
|
||||
"permalink.error.private_channel.button": "Join channel",
|
||||
"permalink.error.private_channel.text": "The message you are trying to view is in a private channel you have not been invited to, but you have access as an admin. Do you still want to join **{channelName}**?",
|
||||
"permalink.error.private_channel.title": "Join private channel",
|
||||
"permalink.error.public_channel_and_team.button": "Join channel and team",
|
||||
"permalink.error.public_channel_and_team.text": "The message you are trying to view is in a channel you don’t belong and a team you are not a member of. Do you want to join **{channelName}** and the **{teamName}** team to view it?",
|
||||
"permalink.error.public_channel_and_team.title": "Join channel and team",
|
||||
"permalink.error.public_channel.button": "Join channel",
|
||||
"permalink.error.public_channel.text": "The message you are trying to view is in a channel you don’t belong to. Do you want to join **{channelName}** to view it?",
|
||||
"permalink.error.public_channel.title": "Join channel",
|
||||
"permalink.show_dialog_warn.cancel": "Cancel",
|
||||
"permalink.show_dialog_warn.description": "You are about to join {channel} without explicitly being added by the channel admin. Are you sure you wish to join this private channel?",
|
||||
"permalink.show_dialog_warn.join": "Join",
|
||||
|
|
|
|||
14
types/components/permalink.d.ts
vendored
Normal file
14
types/components/permalink.d.ts
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
type PermalinkErrorType = {
|
||||
unreachable?: boolean;
|
||||
notExist?: boolean;
|
||||
joinedTeam?: boolean;
|
||||
privateChannel?: boolean;
|
||||
privateTeam?: boolean;
|
||||
teamName?: string;
|
||||
channelName?: string;
|
||||
teamId?: string;
|
||||
channelId?: string;
|
||||
}
|
||||
Loading…
Reference in a new issue