Compare commits

..

79 Commits

Author SHA1 Message Date
Elias Nahum
86508004cf update fastlane 2022-01-13 11:54:00 -03:00
Elias Nahum
4f5bcdcb59 match type 2021-10-01 21:14:18 -03:00
Elias Nahum
e25e179e42 Merge branch 'master' into match 2021-10-01 21:00:04 -03:00
Weblate (bot)
8447d7feea Translations update from Weblate (#5694)
* Translated using Weblate (German)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (French)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/fr/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/nl/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/zh_Hans/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

* Translated using Weblate (Polish)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/pl/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

Translated using Weblate (Turkish)

Currently translated at 100.0% (771 of 771 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

Co-authored-by: JtheBAB <srast@bioc.uzh.ch>
Co-authored-by: Nathanaël <contact@nathanaelhoun.fr>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: aeomin <lin@aeomin.net>
Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
Co-authored-by: kaakaa <stooner.hoe@gmail.com>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
2021-09-30 09:50:44 -03:00
Elias Nahum
523777a207 Use @mattermost/react-native-paste-input to allow pasting of images & files (#5703)
* Use @mattermost/react-native-paste-input to allow pasting of images & files

* upgrade @mattermost/react-native-paste-input
2021-09-30 09:34:57 -03:00
Elias Nahum
d9e8b3e08e Bump app build number to 370 (#5700) 2021-09-28 11:38:35 -03:00
Shaz Amjad
b36dbf9b34 [MM-38683] Android Initialisation Bug + BottomSheet Correction (#5685)
* Fixes various init bugs for android

* Ignores Type Error

* MM-38683: Removes 'cancel' button.

* MM-38683: Removes some 'hideCancel' props.

* Android bottom margin

* Update options modal style

Co-authored-by: Martin Kraft <martin@upspin.org>
Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
2021-09-28 11:28:20 -03:00
Elias Nahum
7e9c574c3f Fix android extension crash (#5696) 2021-09-28 11:27:46 -03:00
Daniel Espino García
3668cb62d3 MM-34811 Add plugin oauth support (#5395)
* Add plugin oauth support

* Fix types

* Switch go to screen by show modal

* Add content width metadata to show correctly the sites

* Remove unneeded metadata

* Fix tsc

* Fix lint

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2021-09-27 18:17:56 +02:00
Daniel Espino García
a2ed6ba3bd Sync with App Command Parser with Webapp (#5631)
* Sync with App Command Parser with Webapp

* Add i18n

* Patch flaky test
2021-09-27 14:54:32 +02:00
Daniel Espino García
dd36545079 [MM-36041] Ensure post options and app commands always have the bindings for its channel (#5563)
* Ensure post options always have the bindings for its channel

* Mimic webapp model

* Address feedback

* Add return to validate bindings

* Address feedback

* Use empty bindings constant to avoid rerenderings

Co-authored-by: Michael Kochell <6913320+mickmister@users.noreply.github.com>
2021-09-24 10:32:58 -04:00
Daniel Espino García
edfd743699 [MM-38216] Add multiteam mentions and saved posts (#5677)
* Add multiteam mentions and saved posts

* Minor fix

* Fix long names

* Add tests, improve separation styling, revert changes on the flagged posts client, and omit the team name when the user only belongs to one team

* Fix separator on iOS

* Update snapshot

* Fix separator

* Fix snapshot

* Differentiate styling between iOS and Android

* Change channelTeamName to teamName
2021-09-24 09:35:01 -03:00
Daniel Espino García
6dbb537f22 Open forms in bindings on all locations (#5665) 2021-09-24 09:34:40 -03:00
Daniel Espino García
aa776e4ae6 Fix warnings on channel info row Formatted Text (#5644) 2021-09-23 21:55:34 +02:00
Amy Blais
1287357e7c Update NOTICE.txt (#5688) 2021-09-22 15:35:30 -03:00
Elias Nahum
ada6be9b7a Update dependencies (#5686)
* Update dependencies

* Fix unsigned builds
2021-09-22 13:54:12 -03:00
Shaz Amjad
58d1454425 Returns empty array for no ids (#5684) 2021-09-21 09:50:36 -04:00
Daniel Espino García
c753be5bfe Sync binding filtering with webapp (#5655)
* Sync binding filtering with webapp

* Add return types and use variable instead of updating actions

* Allow bindings with no call but form with calls
2021-09-21 09:08:35 +02:00
Elias Nahum
2380c520d2 Bump Version to 1.47.0 (#5683)
* Bump app build number to  369

* Bump app version number to  1.47.0
2021-09-20 20:45:48 -03:00
Shaz Amjad
64223efafe MM-28474: Custom Sidebar Categories (#5460)
* Further cleanup and fixes

Tests clean-up

Tests fixed?

Plays nicely with threads

Tests fixed

Fixes ESR and show experimental flags

Failing test fixed

DM Fix

WIP: Bottom bar UX

Fixes for unreads

Failing test

Always show current channel

Create a channel in a category!

* Unreads on top

* Various fixes

* Improves category collapsing

* Passes correct ID through

* Tests cleanup

* Redo unreads and unread-button

* Reverts to just using ids

* More unreads back to using ids

* Uses appropriate selectors for pref updates

* Unreads sorted by recency

* Fixes test for recency

* Fixes re-rendering bug

* Code review updates, websocket event debounced
2021-09-20 14:11:57 -04:00
Weblate (bot)
c784086595 Translations update from Weblate (#5680)
* Translated using Weblate (Spanish)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/es/

* Translated using Weblate (Polish)

Currently translated at 74.7% (573 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/pl/

Co-authored-by: Elias  Nahum <elias@mattermost.com>
Co-authored-by: master7 <marcin.karkosz@rajska.info>
2021-09-17 11:00:13 -05:00
Martin Kraft
c704a752f8 MM-37781: Only evaluates some config settings if the server is less than v6. (#5627)
* MM-37781: Only check deprecated config settings if server is older than v6.

* Feedback review

* Add isMinimumServerVersion helper for iOS Native

* MM-37781: Adds missing parameters.

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
2021-09-15 16:52:39 -04:00
Joseph Baylon
ccba75c8cd Detox/E2E: Minor fix to email (#5676) 2021-09-13 16:38:40 -07:00
Weblate (bot)
dc076713e6 Translations update from Weblate (#5675)
* Translated using Weblate (Japanese)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

Translated using Weblate (Japanese)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 98.8% (758 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/zh_Hans/

Co-authored-by: kaakaa <stooner.hoe@gmail.com>
Co-authored-by: aeomin <lin@aeomin.net>
2021-09-13 10:04:47 +02:00
Ashutosh Kumar
cc6e68fcce Very Minor Change: Updated the way to fetch dependeny from a GIT Repo (#5670)
* Updated the way to fetch dependeny from a GIT Repo

Using a standard way to define dependency via a git repository.
In few system if someone doesn't use SSH way to clone repos then "github:" protocol gives out an error.

* Updated package-lock.json
2021-09-08 14:01:43 -03:00
Kyriakos Z
308637be32 MM-38331: fixes opening notification while in threads (#5664)
Opening a notification while in threads didn't pop the threads screen,
this commit fixes that.
2021-09-07 15:17:04 +03:00
Daniel Espino García
69a65067c3 Remove all checks for minimum versions previous to 5.31 (#5572)
* Remove all checks for minimum versions previous to 5.31

* Fix tests

* Fix bad merge

* Address feedback

* Patch flaky test
2021-09-06 12:57:24 +02:00
Weblate (bot)
45108bde02 Translations update from Weblate (#5668)
* Translated using Weblate (German)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (German)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/nl/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (767 of 767 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

Co-authored-by: JtheBAB <srast@bioc.uzh.ch>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
2021-09-06 09:11:48 +02:00
Elias Nahum
0947baeffe Android clear notification preferences on version change (#5666)
* Android clear notification preferences on version change

* remove spacings
2021-09-04 11:33:34 -04:00
Dean Whillier
fb8238ab0b [MM-37553] Update default themes (#5648)
* new themes and theme type updates

* update theme processing

port newer functionality from webapp

* update theme UI

including new svg-based thumbnail

* lint fixes

* update snapshots and tests

* update theme tile border approach

* remove unused path component

* remove old variable typo

* remove old variable type from theme type

* lint and snapshot updates

* update snapshots
2021-09-03 10:50:24 -04:00
Elias Nahum
29ec86b673 Properly handle notification snooze on Android (#5656) 2021-09-03 09:19:19 -04:00
Elias Nahum
558c90c8da Upgrade iOS minimum version to 12.1 and ESR to 5.37 (#5660) 2021-09-02 09:01:04 -04:00
Elias Nahum
4d9940ea91 Do not resize images to upload (#5661) 2021-09-02 08:42:42 -04:00
Kyriakos Z
8a2a45fd74 MM-35017: participants ordering and inclusion (#5654)
Participants no longer include the thread starter,
thread starter is included only if the user has replied.

This commit changes the ordering of participants to reverse so that the
latest replier is placed first and so forth.

Also the thread starter is not included in the channel view, but is
included in the global threads view.
2021-09-01 17:26:53 -04:00
Dean Whillier
c6cf1f480d [MM-37686] Invert colours for teams button to "fix" starkness on light backgrounds (#5649)
* invert colours for teams button

"fixes" the starkness of the button when using a light sidebar background colour

* update snapshots

* white background for team image
2021-09-01 17:02:28 -04:00
Elias Nahum
1a518111b6 Fix Share extension authentication and error alerts (#5659) 2021-09-01 14:50:19 -04:00
Elias Nahum
8e3044385b MM-38065 Render system messages for guest added or joined a channel (#5639) 2021-09-01 14:32:48 -04:00
Ashish Bhate
c90d040b40 [MM-36792] Consistent query param names (#5643)
Summary
Be consistent with query parameter names: use `per_page` instead of `pageSize` for the Thread API. The server will continue to support the `pageSize` parameter until version 6.0 of the server becomes the minimum server version required for the mobile app. 

Related PRs:
[MM-36792] limit number of threads returned from SQL store mattermost-server#18260
[MM-36792] Consistent query param names mattermost-webapp#8700

Ticket Link
https://mattermost.atlassian.net/browse/MM-36792
2021-08-31 19:20:10 +05:30
Elias Nahum
52a3e22a8d Fix upside down loading message text while scrolling the post list (#5647) 2021-08-31 09:41:34 -04:00
Weblate (bot)
8dd42e2d2a Translations update from Weblate (#5650)
* Translated using Weblate (German)

Currently translated at 99.7% (761 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (German)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (German)

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

Translated using Weblate (German)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

Translated using Weblate (German)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (German)

Currently translated at 100.0% (764 of 764 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

Translated using Weblate (German)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

Translated using Weblate (Turkish)

Currently translated at 100.0% (764 of 764 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

Translated using Weblate (Turkish)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

Translated using Weblate (Swedish)

Currently translated at 100.0% (764 of 764 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

Translated using Weblate (Swedish)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

Translated using Weblate (Swedish)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (764 of 764 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

Translated using Weblate (English (Australia))

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

Translated using Weblate (English (Australia))

Currently translated at 100.0% (763 of 763 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

* Translated using Weblate (French)

Currently translated at 100.0% (764 of 764 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/fr/

* Translated using Weblate (Japanese)

Currently translated at 98.5% (754 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (765 of 765 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/nl/

Co-authored-by: JtheBAB <srast@bioc.uzh.ch>
Co-authored-by: jprusch <rs@schaeferbarthold.de>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
Co-authored-by: Nathanaël <contact@nathanaelhoun.fr>
Co-authored-by: kaakaa <stooner.hoe@gmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
2021-08-30 09:58:36 +02:00
Elias Nahum
742d7ae7ba [MM-38035, MM-35883, MM-38067, MM-36939, MM-36039] Multiple Fixes (#5636) 2021-08-26 21:32:29 -04:00
Daniel Espino García
c29cdef21c [MM-36758] Fix filter and locations (#5567)
* Fix filter and locations

* Fix lint

* Only fetch form on final commands and some other minor fixes

* Fix tests
2021-08-26 10:40:22 +02:00
Ashish Dhama
e6dbd5fbdc [MM-37423] Custom Status: Don't show 'Custom Date and Time' for recent statuses (#5641)
* Custom Status: Don't show 'Custom Date and Time' for recent statuses

* move status boolean out of jsx
2021-08-24 14:41:49 -04:00
Claudio Costa
846aa759b2 [MM-31257] Bump max allowed file uploads per post (#5552)
* Bump max allowed file uploads per post

* Update error string
2021-08-24 18:23:38 +02:00
Weblate (bot)
80af640953 Translations update from Weblate (#5638)
* Translated using Weblate (Turkish)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

Translated using Weblate (Turkish)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

* Update translation files

Updated by "Cleanup translation files" hook in Weblate.

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/

* Translated using Weblate (German)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (French)

Currently translated at 99.3% (749 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/fr/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/nl/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

* Translated using Weblate (Bulgarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/bg/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 89.3% (674 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/pt_BR/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/zh_Hans/

Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: JtheBAB <srast@bioc.uzh.ch>
Co-authored-by: Nathanaël <contact@nathanaelhoun.fr>
Co-authored-by: kaakaa <stooner.hoe@gmail.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Nikolai Zahariev <nikolaiz@yahoo.com>
Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
Co-authored-by: rodrigocorsi <rodrigocorsi@gmail.com>
Co-authored-by: aeomin <lin@aeomin.net>
2021-08-23 09:35:59 +02:00
Kyriakos Z
6896129c73 MM-36980, MM-37030: Opens the thread on push notification and Notifications settings (#5618)
* MM-36980: Opens the thread on push notification

This commit enables tapping on a push notification for a reply to open
the thread.
This is done only if the user has CRT set to 'on'.

* Refactor, and handle in app notifications

* Minor change

* Fixes erroneous check

* Fixes on dismiss in app notification

* Fixes in app push notification for CRT

* Adds CRT notification settings for android

Adds support for CRT (*_threads) notification settings (notify_props).

Adds android comoponents to toggle those settings for push notifications
and email notifications.

* Adds CRT notification settings for iOS

Adds iOS components to toggle those CRT notifications settings
for push notifications and email notifications.

* Fixes bad JSON and intl ids

* Fixes i18n ids

* Fixes tests

* Adds email_threads to the default notify_props

* Fixes push_threads notify_prop default value

* Fixes style, and channel missing on thread open

* Fixes test

* Fixes click notification to open thread

Previous handling of opening the thread on notification clicked fell
into an infinite loop when the app was closed.
This commit fixes that by adding the post to selectedPostId reducer and
then emitting an event to open the thread on channel_base, and only if
the app was started by the notification.

When the app is in the background emitting the event from
handleNotification works just fine.

When the app is in the foreground the notification clicked gets handled
elsewhere and this commit does not change that.

* Removes reply settings when CRT is ON

"Mentions and Replies" section becomes just "Mentions" when the user has
the Collapsed Reply Threads set to "ON".

* Fixes prop types

Co-authored-by: Kyriakos Ziakoulis <koox00@Kyriakoss-MacBook-Pro.local>
2021-08-20 19:49:00 +03:00
Ashish Bhate
8228ed3400 [MM-37602] fix channel unread filtering for CRT (#5622)
Summary:
Fixes filtering of unread channels with CRT

Ticket Link:
https://mattermost.atlassian.net/browse/MM-37602

This PR was tested on:
ios 12 simulator, ios 14.4
2021-08-19 19:58:56 +05:30
Claudio Costa
7f69a1adf9 Remove Posts.ParentId (#5541) 2021-08-18 16:39:42 +02:00
Daniel Espino García
c1e5582cc0 Fix interactive message submit button by adding a default when none is defined (#5551)
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2021-08-17 13:12:33 +02:00
Daniel Espino García
b7fcda3956 [MM-34415, MM-34808, MM-34572, MM-34385, MM-32445, MM-31525] Handle user and channel provider from the app parser (#5503)
* Handle user and channel provider from the app parser

* Do not process mapStateToProps on appsTakeOver

* Fix tsc

* Address feedback

* Fix broken reference

* Address feedback and fix tests

* Fix i18n

* Use instantiated teamID on parser context

* Address feedback

* Fix test

* Address feedback

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2021-08-17 10:45:49 +02:00
Amy Blais
0251a19aa9 Update en.json (#5629) 2021-08-16 11:00:21 -04:00
Weblate (bot)
115e74a67a Translations update from Weblate (#5628)
* Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (Bulgarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/bg/

Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: Nikolai Zahariev <nikolaiz@yahoo.com>
2021-08-16 11:01:00 +02:00
Matthew Birtch
2df9642456 updated threads illustration SVG to align with new branding (#5619)
* updated threads illustration SVG to align with new branding

* fixed issue with svg on android
2021-08-15 10:41:58 -04:00
Michael Kochell
6e35286051 [MM-33600, MM-34679] Apps commands invalidate form cache (#5333)
* invalidate parser form cache on channel navigate and when changing commands

* lint

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2021-08-13 15:57:03 -04:00
Elias Nahum
f7eecacccb Bump app build number to 368 (#5625) 2021-08-13 14:49:34 -04:00
Elias Nahum
a44a19d125 [MM-37840, MM-37841] do not mark channel as read when clearing push notifications (#5623)
* MM-37840 do not mark channel as read when clearing push notifications

* MM-37841 prevent from setting the edit post screen buttons with every key press
2021-08-13 13:00:09 -04:00
Matthew Birtch
066e005158 MM-37662 Update App Icon to New Brand Colors (#5603)
* adds updated icon files to align with new branding colors

* small tweak to icon colors
2021-08-13 10:03:03 -04:00
Matthew Birtch
ced61af9d3 MM-37092 Update Splash Screen to align with new branding (#5610)
* reworking splash screen for new brand modifying layout

* removed background_splash file and reworked launch_screen file instead

* simplified to reduce number of changed files

* updated release launch screen as well

* reworked to simplify changes

* removed iOS splash background image not being used for this PR

* added support for dark mode

* tweak to splash background to center better

* update fastlane

* Replace iOS Splash Screen release assets

* Replace Android Splash Screen release assets

* Replace iOS release LaunchScreen.storyboard

Co-authored-by: Elias Nahum <nahumhbl@gmail.com>
2021-08-13 10:02:31 -04:00
Elias Nahum
8953f29623 Android Send Notification event to JS only once when the app is in the foreground (#5620) 2021-08-12 13:46:03 -04:00
Elias Nahum
faa3ee05ba Bump app build number to 367 (#5616) 2021-08-11 09:54:36 -04:00
Anurag Shivarathri
fc929891ea MM-37485 MM-37602 MM-37610 MM-37684 MM-37719 MM-37522 MM-37720 App crash, Sync issue fixes (#5612)
Summary
Fixes app crash on opening channel header
Fixes app crash on opening permalink from permalink screen
Fixes showing duplicates channels while searching in "Jump to..."
Fixes auto following the thread on opening the thread view when there are unreads
Fixes updation of threads state (Read/Unread/Deleted) of already loaded threads
Fixes counter showing as blank due to threads sync issue
Doesn't show Follow Thread/Message when CRT is not enabled

Ticket Link
https://mattermost.atlassian.net/browse/MM-37485
https://mattermost.atlassian.net/browse/MM-37602
https://mattermost.atlassian.net/browse/MM-37610
https://mattermost.atlassian.net/browse/MM-37684
https://mattermost.atlassian.net/browse/MM-37719
https://mattermost.atlassian.net/browse/MM-37522
https://mattermost.atlassian.net/browse/MM-37720

Device Information
This PR was tested on: iOS 14.5
2021-08-11 15:56:38 +05:30
Weblate (bot)
e280400994 Translations update from Weblate (#5614)
* Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (Swedish)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/sv/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 99.8% (753 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 99.8% (753 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 99.8% (753 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (Japanese)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

Co-authored-by: Zsolt Godó <zsolttokio@gmail.com>
Co-authored-by: MArtin Johnson <martinjohnson@bahnhof.se>
Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: kaakaa <stooner.hoe@gmail.com>
2021-08-10 10:37:12 +02:00
Manoj Malik
340ec81b25 MM-37608 and MM-37416 issue fixes (#5592)
* Fixed the MM-37608 issue

* Fixed the MM-37416 issue
2021-08-09 22:57:38 -04:00
Michael Kochell
fd0cc90160 [MM-35617] App modals are now opened from components instead of actions (#5394)
* proper fix for opening app form modal and url navigation

* complete merge with changes

* add useCallback check for theme

* lint
2021-08-06 11:21:31 -04:00
Elias Nahum
7cdbe095a1 MM-37577 Do not set post id when posting a message (#5602)
* MM-37577 Do not set post id when posting a message

* Add unit test to verify that creating a post always send an empty string as the id
2021-08-06 10:51:52 -04:00
Elias Nahum
4837ff5d70 Specify screenId for files uploads handler (#5595) 2021-08-06 09:16:49 -04:00
Elias Nahum
fdf93ae0c5 MM-37674 Fix android push notification crash (#5601) 2021-08-06 09:00:14 -04:00
Elias Nahum
3ac73e808b MM-37666 Properly dismiss edit profile screen (#5599)
* MM-37666 Properly dismiss edit profile screen

* pass componentId to modal being dismissed
2021-08-06 08:57:43 -04:00
Elias Nahum
a7b604e8c9 MM-37660 Fix keep mention for channel A when opening a push notification on channel B (#5597)
* Fix keep mention for channel A when opening a push notification on channel B

* properly fix race condition

* Load channels and channel members when opening the app from a push notification
2021-08-05 19:56:36 -07:00
Elias Nahum
3d5f8fbf9b Fix android share extension crash (#5596) 2021-08-05 01:32:01 -04:00
Manoj Malik
1be9129112 Fixed the custom status invalid prop warning issue in ChannelInfo screen (#5589) 2021-08-03 08:49:02 -04:00
Weblate (bot)
583e6b032f Translations update from Weblate (#5587)
* Translated using Weblate (Russian)

Currently translated at 100.0% (752 of 752 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ru/

Translated using Weblate (Russian)

Currently translated at 99.6% (749 of 752 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ru/

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 100.0% (752 of 752 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

Translated using Weblate (Hungarian)

Currently translated at 99.3% (747 of 752 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/hu/

* Translated using Weblate (Japanese)

Currently translated at 95.2% (716 of 752 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/ja/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/zh_Hans/

Translated using Weblate (Chinese (Simplified))

Currently translated at 100.0% (752 of 752 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/de/

* Translated using Weblate (Turkish)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/tr/

* Translated using Weblate (Spanish)

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/es/

* Translated using Weblate (Dutch)

Currently translated at 99.4% (750 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/nl/

* Translated using Weblate (English (Australia))

Currently translated at 100.0% (754 of 754 strings)

Translation: mattermost-languages-shipped/mattermost-mobile
Translate-URL: https://translate.mattermost.com/projects/mattermost/mattermost-mobile_master/en_AU/

Co-authored-by: Alexey Napalkov <flynbit@gmail.com>
Co-authored-by: Tóth Csaba // Online ERP Hungary Kft <csaba.toth@online-erp.hu>
Co-authored-by: kaakaa <stooner.hoe@gmail.com>
Co-authored-by: aeomin <lin@aeomin.net>
Co-authored-by: JtheBAB <srast@bioc.uzh.ch>
Co-authored-by: Kaya Zeren <kayazeren@gmail.com>
Co-authored-by: Elias  Nahum <elias@mattermost.com>
Co-authored-by: Tom De Moor <tom@controlaltdieliet.be>
Co-authored-by: Matthew Williams <Matthew.Williams@outlook.com.au>
2021-08-02 09:20:43 +02:00
Elias Nahum
813af2199d Bump app build number to 366 (#5584) 2021-07-30 10:47:15 -04:00
Anurag Shivarathri
ed1cc2a51d MM-37294 MM-37296 MM-37297 MM-37495 MM-37509 CRT fixes (#5574)
* fixes MM-37294 MM-37296 MM-37297

* Added conditions to check for post & thread existence

* Update app/mm-redux/selectors/entities/threads.ts

Co-authored-by: Kyriakos Z. <3829551+koox00@users.noreply.github.com>

* type fix

* Never disabling Mark All as unread

* Added follow/unfollow message for not yet thread posts

* Test case fix for mark all as unread enabled all the time

* Removed hardcoded condition

* Fixed MM-37509

* Updated snapshot for sidebar

Co-authored-by: Kyriakos Z. <3829551+koox00@users.noreply.github.com>
Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
2021-07-30 11:14:01 +05:30
Michael Kochell
0e0ed0b14b MM-31964 Set default value of bool form field to false (#5388)
* set bool default to false

* add tests

lint

* update tests

* import order

* import order
2021-07-29 20:23:43 -04:00
Elias Nahum
29fd07ede6 Upgrade Dependencies (#5578)
* Dependency updates

* Ensure post list starts at the beginning on channel switch

* add missing prop to settings_sidebar test

* Update detox deps
2021-07-29 19:06:37 -04:00
Amy Blais
a70ca4bac3 Update NOTICE.txt (#5579) 2021-07-29 17:12:35 -04:00
Anurag Shivarathri
2a641afc66 MM-37456 "Threads" item in the sidebar should not scroll (#5575)
* Made threads item as static

* Updated snapshot

* Moved from Text to FormattedText

* Updated snapshot .. AGAIN

* Removed 8px margin bottom from threads sidebar item
2021-07-29 18:43:56 +05:30
Elias Nahum
62e1fdac7d Get Apple API key for match adhoc lane 2021-07-06 13:58:35 -04:00
844 changed files with 28306 additions and 33430 deletions

View File

@@ -14,7 +14,7 @@ executors:
NODE_ENV: production
BABEL_ENV: production
docker:
- image: circleci/android:api-29-node
- image: circleci/android:api-30-node
working_directory: ~/mattermost-mobile
resource_class: <<parameters.resource_class>>
@@ -24,7 +24,7 @@ executors:
NODE_ENV: production
BABEL_ENV: production
macos:
xcode: "12.1.0"
xcode: "13.0.0"
working_directory: ~/mattermost-mobile
shell: /bin/bash --login -o pipefail

View File

@@ -23,9 +23,6 @@ node_modules/react-native/flow/
[options]
emoji=true
esproposal.optional_chaining=enable
esproposal.nullish_coalescing=enable
exact_by_default=true
module.file_ext=.js
@@ -64,4 +61,4 @@ untyped-import
untyped-type-import
[version]
^0.137.0
^0.149.0

View File

@@ -532,6 +532,29 @@ SOFTWARE.
---
## @types/redux-mock-store
This product contains '@types/redux-mock-store' by Redux.
A mock store for testing Redux async action creators and middleware. The mock store will create an array of dispatched actions which serve as an action log for tests.
* HOMEPAGE:
* https://github.com/reduxjs/redux-mock-store
* LICENSE: MIT
The MIT License (MIT)
Copyright (c) 2017 Arnaud Benard
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
## analytics-react-native
This product contains a modified version of 'analytics-react-native' by Segment.

View File

@@ -1,6 +1,6 @@
# Mattermost Mobile
- **Minimum Server versions:** Current ESR version (5.31.3)
- **Minimum Server versions:** Current ESR version (5.37.0)
- **Supported iOS versions:** 11+
- **Supported Android versions:** 7.0+

View File

@@ -122,18 +122,13 @@ def enableHermes = project.ext.react.get("enableHermes", false);
android {
compileSdkVersion rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId "com.mattermost.rnbeta"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60"
versionCode 368
versionName "1.46.0"
versionCode 370
versionName "1.47.0"
multiDexEnabled = true
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
@@ -269,7 +264,7 @@ dependencies {
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
from configurations.implementation
into 'libs'
}

View File

@@ -1,10 +1,14 @@
package com.mattermost.rnbeta;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import androidx.annotation.Nullable;
@@ -31,6 +35,7 @@ import org.json.JSONObject;
public class CustomPushNotification extends PushNotification {
private static final String PUSH_NOTIFICATIONS = "PUSH_NOTIFICATIONS";
private static final String VERSION_PREFERENCE = "VERSION_PREFERENCE";
private static final String PUSH_TYPE_MESSAGE = "message";
private static final String PUSH_TYPE_CLEAR = "clear";
private static final String PUSH_TYPE_SESSION = "session";
@@ -39,6 +44,29 @@ public class CustomPushNotification extends PushNotification {
public CustomPushNotification(Context context, Bundle bundle, AppLifecycleFacade appLifecycleFacade, AppLaunchHelper appLaunchHelper, JsIOHelper jsIoHelper) {
super(context, bundle, appLifecycleFacade, appLaunchHelper, jsIoHelper);
CustomPushNotificationHelper.createNotificationChannels(context);
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
String version = String.valueOf(pInfo.versionCode);
String storedVersion = null;
SharedPreferences pSharedPref = context.getSharedPreferences(VERSION_PREFERENCE, Context.MODE_PRIVATE);
if (pSharedPref != null) {
storedVersion = pSharedPref.getString("Version", "");
}
if (!version.equals(storedVersion)) {
if (pSharedPref != null) {
SharedPreferences.Editor editor = pSharedPref.edit();
editor.putString("Version", version);
editor.apply();
}
Map<String, List<Integer>> inputMap = new HashMap<>();
saveNotificationsMap(context, inputMap);
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
public static void cancelNotification(Context context, String channelId, Integer notificationId) {
@@ -49,10 +77,23 @@ public class CustomPushNotification extends PushNotification {
return;
}
notifications.remove(notificationId);
saveNotificationsMap(context, notificationsInChannel);
final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
final NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.cancel(notificationId);
notifications.remove(notificationId);
final StatusBarNotification[] statusNotifications = notificationManager.getActiveNotifications();
boolean hasMore = false;
for (final StatusBarNotification status : statusNotifications) {
if (status.getNotification().extras.getString("channel_id").equals(channelId)) {
hasMore = true;
break;
}
}
if (!hasMore) {
notificationsInChannel.remove(channelId);
}
saveNotificationsMap(context, notificationsInChannel);
}
}

View File

@@ -57,7 +57,6 @@ private final ReactNativeHost mReactNativeHost =
// Packages that cannot be auto linked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new RNNotificationsPackage(MainApplication.this));
packages.add(new RNPasteableTextInputPackage());
packages.add(
new TurboReactPackage() {
@Override

View File

@@ -1,7 +0,0 @@
package com.mattermost.rnbeta;
import android.net.Uri;
public interface RNEditTextOnPasteListener {
void onPaste(Uri itemUri);
}

View File

@@ -1,98 +0,0 @@
package com.mattermost.rnbeta;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
public class RNPasteableActionCallback implements ActionMode.Callback {
private final RNPasteableEditText mEditText;
RNPasteableActionCallback(RNPasteableEditText editText) {
mEditText = editText;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
Bundle config = MainApplication.instance.getManagedConfig();
if (config != null) {
WritableMap result = Arguments.fromBundle(config);
String copyPasteProtection = result.getString("copyAndPasteProtection");
assert copyPasteProtection != null;
if (copyPasteProtection.equals("true")) {
disableMenus(menu);
}
}
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
Uri uri = this.getUriInClipboard();
if (item.getItemId() == android.R.id.paste && uri != null) {
mEditText.getOnPasteListener().onPaste(uri);
mode.finish();
} else {
mEditText.onTextContextMenuItem(item.getItemId());
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
private void disableMenus(Menu menu) {
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
int id = item.getItemId();
boolean shouldDisableMenu = (
id == android.R.id.paste
|| id == android.R.id.copy
|| id == android.R.id.cut
);
item.setEnabled(!shouldDisableMenu);
}
}
private Uri getUriInClipboard() {
ClipboardManager clipboardManager = (ClipboardManager) mEditText.getContext().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboardManager.getPrimaryClip();
if (clipData == null) {
return null;
}
ClipData.Item item = clipData.getItemAt(0);
if (item == null) {
return null;
}
CharSequence chars = item.getText();
if (chars == null) {
return null;
}
String text = chars.toString();
if (text.length() > 0) {
return null;
}
return item.getUri();
}
}

View File

@@ -1,22 +0,0 @@
package com.mattermost.rnbeta;
import android.content.Context;
import com.facebook.react.views.textinput.ReactEditText;
public class RNPasteableEditText extends ReactEditText {
private RNEditTextOnPasteListener mOnPasteListener;
public RNPasteableEditText(Context context) {
super(context);
}
public void setOnPasteListener(RNEditTextOnPasteListener listener) {
mOnPasteListener = listener;
}
public RNEditTextOnPasteListener getOnPasteListener() {
return mOnPasteListener;
}
}

View File

@@ -1,163 +0,0 @@
package com.mattermost.rnbeta;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.net.Uri;
import android.os.Build;
import android.util.Patterns;
import android.webkit.MimeTypeMap;
import android.webkit.URLUtil;
import androidx.annotation.RequiresApi;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.mattermost.share.RealPathUtil;
import com.mattermost.share.ShareModule;
import java.io.FileNotFoundException;
import java.io.File;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Matcher;
public class RNPasteableEditTextOnPasteListener implements RNEditTextOnPasteListener {
private final RNPasteableEditText mEditText;
RNPasteableEditTextOnPasteListener(RNPasteableEditText editText) {
mEditText = editText;
}
@Override
public void onPaste(Uri itemUri) {
ReactContext reactContext = (ReactContext)mEditText.getContext();
String uri = itemUri.toString();
WritableArray images = null;
WritableMap error = null;
String uriMimeType = reactContext.getContentResolver().getType(itemUri);
if (uriMimeType == null) {
return;
}
// Special handle for Google docs
if (uri.equals("content://com.google.android.apps.docs.editors.kix.editors.clipboard")) {
ClipboardManager clipboardManager = (ClipboardManager) reactContext.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = clipboardManager.getPrimaryClip();
if (clipData == null) {
return;
}
ClipData.Item item = clipData.getItemAt(0);
String htmlText = item.getHtmlText();
// Find uri from html
Matcher matcher = Patterns.WEB_URL.matcher(htmlText);
if (matcher.find()) {
uri = htmlText.substring(matcher.start(1), matcher.end());
}
}
if (uri.startsWith("http")) {
Thread pastImageFromUrlThread = new Thread(new RNPasteableImageFromUrl(reactContext, mEditText, uri));
pastImageFromUrlThread.start();
return;
}
uri = RealPathUtil.getRealPathFromURI(reactContext, itemUri);
if (uri == null) {
return;
}
// Get type
String extension = MimeTypeMap.getFileExtensionFromUrl(uri);
if (extension == null) {
return;
}
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
if (mimeType == null) {
return;
}
// Get fileName
String fileName = URLUtil.guessFileName(uri, null, mimeType);
if (uri.contains(ShareModule.CACHE_DIR_NAME) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
uri = moveToImagesCache(uri, fileName);
}
if (uri == null) {
return;
}
// Get fileSize
long fileSize;
try {
ContentResolver contentResolver = reactContext.getContentResolver();
AssetFileDescriptor assetFileDescriptor = contentResolver.openAssetFileDescriptor(itemUri, "r");
if (assetFileDescriptor == null) {
return;
}
fileSize = assetFileDescriptor.getLength();
WritableMap image = Arguments.createMap();
image.putString("type", mimeType);
image.putDouble("fileSize", fileSize);
image.putString("fileName", fileName);
image.putString("uri", "file://" + uri);
images = Arguments.createArray();
images.pushMap(image);
} catch (FileNotFoundException e) {
error = Arguments.createMap();
error.putString("message", e.getMessage());
}
WritableMap event = Arguments.createMap();
event.putArray("data", images);
event.putMap("error", error);
reactContext
.getJSModule(RCTEventEmitter.class)
.receiveEvent(
mEditText.getId(),
"onPaste",
event
);
}
@RequiresApi(api = Build.VERSION_CODES.O)
private String moveToImagesCache(String src, String fileName) {
ReactContext ctx = (ReactContext)mEditText.getContext();
String cacheFolder = ctx.getCacheDir().getAbsolutePath() + "/Images/";
String dest = cacheFolder + fileName;
File folder = new File(cacheFolder);
try {
if (!folder.exists()) {
boolean created = folder.mkdirs();
if (!created) {
return null;
}
}
Files.move(Paths.get(src), Paths.get(dest));
} catch (FileAlreadyExistsException fileError) {
// Do nothing and return dest path
} catch (Exception err) {
return null;
}
return dest;
}
}

View File

@@ -1,76 +0,0 @@
package com.mattermost.rnbeta;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.events.RCTEventEmitter;
import com.facebook.react.views.textinput.ReactEditText;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
public class RNPasteableImageFromUrl implements Runnable {
private final ReactContext mContext;
private final String mUri;
private final ReactEditText mTarget;
RNPasteableImageFromUrl(ReactContext context, ReactEditText target, String uri) {
mContext = context;
mUri = uri;
mTarget = target;
}
@Override
public void run() {
WritableArray images = null;
WritableMap error = null;
try {
URL url = new URL(mUri);
URLConnection u = url.openConnection();
// Get type
String mimeType = u.getHeaderField("Content-Type");
if (!mimeType.startsWith("image")) {
return;
}
// Get fileSize
long fileSize = Long.parseLong(u.getHeaderField("Content-Length"));
// Get fileName
String contentDisposition = u.getHeaderField("Content-Disposition");
int startIndex = contentDisposition.indexOf("filename=\"") + 10;
int endIndex = contentDisposition.length() - 1;
String fileName = contentDisposition.substring(startIndex, endIndex);
WritableMap image = Arguments.createMap();
image.putString("type", mimeType);
image.putDouble("fileSize", fileSize);
image.putString("fileName", fileName);
image.putString("uri", mUri);
images = Arguments.createArray();
images.pushMap(image);
} catch (IOException e) {
error = Arguments.createMap();
error.putString("message", e.getMessage());
}
WritableMap event = Arguments.createMap();
event.putArray("data", images);
event.putMap("error", error);
mContext
.getJSModule(RCTEventEmitter.class)
.receiveEvent(
mTarget.getId(),
"onPaste",
event
);
}
}

View File

@@ -1,85 +0,0 @@
package com.mattermost.rnbeta;
import androidx.annotation.NonNull;
import androidx.core.view.inputmethod.EditorInfoCompat;
import androidx.core.view.inputmethod.InputConnectionCompat;
import android.text.InputType;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.views.textinput.ReactEditText;
import com.facebook.react.views.textinput.ReactTextInputManager;
import java.util.Map;
import javax.annotation.Nullable;
public class RNPasteableTextInputManager extends ReactTextInputManager {
@Override
@NonNull
public String getName() {
return "PasteableTextInputAndroid";
}
@Override
@NonNull
public ReactEditText createViewInstance(ThemedReactContext context) {
RNPasteableEditText editText = new RNPasteableEditText(context) {
@Override
public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
final InputConnection ic = super.onCreateInputConnection(editorInfo);
EditorInfoCompat.setContentMimeTypes(editorInfo,
new String [] {"image/*"});
final InputConnectionCompat.OnCommitContentListener callback =
(inputContentInfo, flags, opts) -> {
// read and display inputContentInfo asynchronously
if ((flags &
InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
try {
inputContentInfo.requestPermission();
}
catch (Exception e) {
return false;
}
}
this.getOnPasteListener().onPaste(inputContentInfo.getContentUri());
return true;
};
return InputConnectionCompat.createWrapper(ic, editorInfo, callback);
}
};
int inputType = editText.getInputType();
editText.setInputType(inputType & (~InputType.TYPE_TEXT_FLAG_MULTI_LINE));
editText.setReturnKeyType("done");
editText.setCustomInsertionActionModeCallback(new RNPasteableActionCallback(editText));
editText.setCustomSelectionActionModeCallback(new RNPasteableActionCallback(editText));
return editText;
}
@Override
protected void addEventEmitters(ThemedReactContext reactContext, ReactEditText editText) {
super.addEventEmitters(reactContext, editText);
RNPasteableEditText pasteableEditText = (RNPasteableEditText)editText;
pasteableEditText.setOnPasteListener(new RNPasteableEditTextOnPasteListener(pasteableEditText));
}
@Nullable
@Override
public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
Map<String, Object> map = super.getExportedCustomBubblingEventTypeConstants();
assert map != null;
map.put(
"onPaste",
MapBuilder.of(
"phasedRegistrationNames",
MapBuilder.of("bubbled", "onPaste")));
return map;
}
}

View File

@@ -1,28 +0,0 @@
package com.mattermost.rnbeta;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
public class RNPasteableTextInputPackage implements ReactPackage {
@Nonnull
@Override
public List<NativeModule> createNativeModules(@Nonnull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Nonnull
@Override
public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
return Arrays.asList(
new RNPasteableTextInputManager()
);
}
}

BIN
android/app/src/main/res/drawable-hdpi/splash.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 KiB

BIN
android/app/src/main/res/drawable-mdpi/splash.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

BIN
android/app/src/main/res/drawable-xhdpi/splash.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
android/app/src/main/res/drawable-xxhdpi/splash.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
android/app/src/main/res/drawable-xxxhdpi/splash.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -1,19 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:gravity="center_horizontal"
tools:context=".SplashScreenActivity">
android:background="@color/splashscreen_bg"
android:orientation="vertical">
<ImageView
android:id="@+id/imgLogo"
android:id="@+id/splashBackgroundImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:src="@drawable/splash" />
android:scaleType="centerCrop"
android:src="@drawable/splash_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/splashIcon"
android:layout_width="96dp"
android:layout_height="96dp"
android:contentDescription="@string/app_name"
android:src="@drawable/splash"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 855 B

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 638 B

BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 847 B

After

Width:  |  Height:  |  Size: 481 B

BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 985 B

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 847 B

BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="white">#FFFFFF</color>
<color name="transparent">#00000000</color>
<color name="splashscreen_bg">#1E325C</color>
</resources>

View File

@@ -2,4 +2,5 @@
<resources>
<color name="white">#FFFFFF</color>
<color name="transparent">#00000000</color>
</resources>
<color name="splashscreen_bg">#FFFFFF</color>
</resources>

View File

@@ -3,8 +3,8 @@
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowBackground">@color/splashscreen_bg</item>
</style>
</resources>

View File

@@ -2,15 +2,15 @@
buildscript {
ext {
buildToolsVersion = "29.0.3"
buildToolsVersion = "30.0.2"
minSdkVersion = 24
compileSdkVersion = 29
targetSdkVersion = 29
compileSdkVersion = 30
targetSdkVersion = 30
supportLibVersion = "28.0.0"
kotlinVersion = "1.3.61"
kotlinVersion = "1.5.30"
firebaseVersion = "21.0.0"
RNNKotlinVersion = kotlinVersion
ndkVersion = "21.1.6352462"
ndkVersion = "20.1.5948944"
}
repositories {
@@ -20,7 +20,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:4.2.1'
classpath 'com.google.gms:google-services:4.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"

View File

@@ -30,4 +30,4 @@ android.useAndroidX=true
android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.75.1
FLIPPER_VERSION=0.93.0

View File

@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9-all.zip

View File

@@ -3,22 +3,15 @@
import {sendEphemeralPost} from '@actions/views/post';
import {Client4} from '@client/rest';
import CompassIcon from '@components/compass_icon';
import {handleGotoLocation} from '@mm-redux/actions/integrations';
import {AppCallTypes, AppCallResponseTypes} from '@mm-redux/constants/apps';
import {getTheme} from '@mm-redux/selectors/entities/preferences';
import {ActionFunc, DispatchFunc} from '@mm-redux/types/actions';
import {AppCallResponse, AppForm, AppCallRequest, AppCallType, AppContext} from '@mm-redux/types/apps';
import {AppCallResponse, AppCallRequest, AppCallType, AppContext} from '@mm-redux/types/apps';
import {CommandArgs} from '@mm-redux/types/integrations';
import {Post} from '@mm-redux/types/posts';
import {Theme} from '@mm-redux/types/preferences';
import EphemeralStore from '@store/ephemeral_store';
import {makeCallErrorResponse} from '@utils/apps';
import {showModal} from './navigation';
import {cleanForm, makeCallErrorResponse} from '@utils/apps';
export function doAppCall<Res=unknown>(call: AppCallRequest, type: AppCallType, intl: any): ActionFunc {
return async (dispatch, getState) => {
return async () => {
try {
const res = await Client4.executeAppCall(call, type) as AppCallResponse<Res>;
const responseType = res.type || AppCallResponseTypes.OK;
@@ -37,10 +30,7 @@ export function doAppCall<Res=unknown>(call: AppCallRequest, type: AppCallType,
return {error: makeCallErrorResponse(errMsg)};
}
const screen = EphemeralStore.getNavigationTopComponentId();
if (type === AppCallTypes.SUBMIT && screen !== 'AppForm') {
showAppForm(res.form, call, getTheme(getState()));
}
cleanForm(res.form);
return {data: res};
}
@@ -61,8 +51,6 @@ export function doAppCall<Res=unknown>(call: AppCallRequest, type: AppCallType,
return {error: makeCallErrorResponse(errMsg)};
}
dispatch(handleGotoLocation(res.navigate_to_url, intl));
return {data: res};
default: {
const errMsg = intl.formatMessage({
@@ -84,34 +72,6 @@ export function doAppCall<Res=unknown>(call: AppCallRequest, type: AppCallType,
};
}
const showAppForm = async (form: AppForm, call: AppCallRequest, theme: Theme) => {
const closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor);
let submitButtons;
const customSubmitButtons = form.submit_buttons && form.fields.find((f) => f.name === form.submit_buttons)?.options;
if (!customSubmitButtons?.length) {
submitButtons = [{
id: 'submit-form',
showAsAction: 'always',
text: 'Submit',
}];
}
const options = {
topBar: {
leftButtons: [{
id: 'close-dialog',
icon: closeButton,
}],
rightButtons: submitButtons,
},
};
const passProps = {form, call};
showModal('AppForm', form.title, passProps, options);
};
export function postEphemeralCallResponseForPost(response: AppCallResponse, message: string, post: Post): ActionFunc {
return (dispatch: DispatchFunc) => {
return dispatch(sendEphemeralPost(

View File

@@ -328,7 +328,8 @@ function fetchDirectMessageProfileIfNeeded(state: GlobalState, channel: Channel,
const otherUserId = getUserIdFromChannelName(currentUserId, channel.name);
const otherUser = users[otherUserId];
const dmVisible = isDirectChannelVisible(currentUserId, myPreferences, channel);
const dmAutoClosed = isAutoClosed(config, myPreferences, channel, channel.last_post_at, otherUser ? otherUser.delete_at : 0, currentChannelId);
const {serverVersion} = state.entities.general;
const dmAutoClosed = isAutoClosed(config, myPreferences, channel, channel.last_post_at, otherUser ? otherUser.delete_at : 0, currentChannelId, undefined, serverVersion);
const member = channelMembers.find((cm) => cm.channel_id === channel.id);
const dmIsUnread = member ? member.mention_count > 0 : false;
const dmFetchProfile = dmIsUnread || (dmVisible && !dmAutoClosed);
@@ -355,7 +356,9 @@ function fetchGroupMessageProfilesIfNeeded(state: GlobalState, channel: Channel,
const myPreferences = getMyPreferences(state);
const config = getConfig(state);
const gmVisible = isGroupChannelVisible(myPreferences, channel);
const gmAutoClosed = isAutoClosed(config, myPreferences, channel, channel.last_post_at, 0);
const {serverVersion} = state.entities.general;
const currentChannelId = getCurrentChannelId(state);
const gmAutoClosed = isAutoClosed(config, myPreferences, channel, channel.last_post_at, 0, currentChannelId, undefined, serverVersion);
const channelMember = channelMembers.find((cm) => cm.channel_id === channel.id);
let hasMentions = false;
let isUnread = false;

View File

@@ -5,6 +5,7 @@ import merge from 'deepmerge';
import {Keyboard, Platform} from 'react-native';
import {Navigation} from 'react-native-navigation';
import CompassIcon from '@components/compass_icon';
import {DeviceTypes, NavigationTypes} from '@constants';
import {CHANNEL} from '@constants/screen';
import {Preferences} from '@mm-redux/constants';
@@ -91,7 +92,7 @@ export function resetToChannel(passProps = {}) {
}
export function resetToSelectServer(allowOtherServers) {
const theme = Preferences.THEMES.default;
const theme = Preferences.THEMES.denim;
EphemeralStore.clearNavigationComponents();
@@ -291,7 +292,7 @@ export function showModal(name, title, passProps = {}, options = {}) {
}
export function showModalOverCurrentContext(name, passProps = {}, options = {}) {
const title = '';
const title = passProps.title || '';
let animations;
switch (Platform.OS) {
@@ -372,6 +373,34 @@ export function showSearchModal(initialValue = '') {
showModal(name, title, passProps, options);
}
export const showAppForm = async (form, call, theme) => {
const closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor);
let submitButtons;
const customSubmitButtons = form.submit_buttons && form.fields.find((f) => f.name === form.submit_buttons)?.options;
if (!customSubmitButtons?.length) {
submitButtons = [{
id: 'submit-form',
showAsAction: 'always',
text: 'Submit',
}];
}
const options = {
topBar: {
leftButtons: [{
id: 'close-dialog',
icon: closeButton,
}],
rightButtons: submitButtons,
},
};
const passProps = {form, call};
showModal('AppForm', form.title, passProps, options);
};
export async function dismissModal(options = {}) {
if (!EphemeralStore.hasModalsOpened()) {
return;
@@ -428,6 +457,13 @@ export function showOverlay(name, passProps, options = {}) {
overlay: {
interceptTouchOutside: false,
},
...Platform.select({
android: {
statusBar: {
drawBehind: true,
},
},
}),
};
Navigation.showOverlay({

View File

@@ -37,7 +37,7 @@ describe('@actions/navigation', () => {
const topComponentId = 'top-component-id';
const name = 'name';
const title = 'title';
const theme = Preferences.THEMES.default;
const theme = Preferences.THEMES.denim;
const passProps = {
testProp: 'prop',
};

View File

@@ -1,6 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable max-lines */
import {batchActions} from 'redux-batched-actions';
import {lastChannelIdForTeam, loadSidebarDirectMessagesProfiles} from '@actions/helpers/channels';
@@ -10,6 +12,7 @@ import {ViewTypes} from '@constants';
import {INSERT_TO_COMMENT, INSERT_TO_DRAFT} from '@constants/post_draft';
import {ChannelTypes, RoleTypes, GroupTypes} from '@mm-redux/action_types';
import {fetchAppBindings} from '@mm-redux/actions/apps';
import {fetchMyCategories} from '@mm-redux/actions/channel_categories';
import {
fetchMyChannelsAndMembers,
getChannelByName,
@@ -33,11 +36,11 @@ import {getTeamByName as selectTeamByName, getCurrentTeam, getTeamMemberships} f
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
import {getChannelByName as selectChannelByName, getChannelsIdForTeam} from '@mm-redux/utils/channel_utils';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
import {getChannelReachable} from '@selectors/channel';
import {getViewingGlobalThreads} from '@selectors/threads';
import telemetry, {PERF_MARKERS} from '@telemetry';
import {appsEnabled} from '@utils/apps';
import {shouldShowLegacySidebar} from '@utils/categories';
import {isDirectChannelVisible, isGroupChannelVisible, getChannelSinceValue, privateChannelJoinPrompt} from '@utils/channels';
import {isPendingPost} from '@utils/general';
@@ -637,11 +640,10 @@ function loadGroupData(isReconnect = false) {
const actions = [];
const team = getCurrentTeam(state);
const currentUserId = getCurrentUserId(state);
const serverVersion = state.entities.general.serverVersion;
const license = getLicense(state);
const hasLicense = license?.IsLicensed === 'true' && license?.LDAPGroups === 'true';
if (hasLicense && team && isMinimumServerVersion(serverVersion, 5, 24)) {
if (hasLicense && team) {
for (let i = 0; i <= MAX_RETRIES; i++) {
try {
if (team.group_constrained) {
@@ -745,6 +747,10 @@ export function loadChannelsForTeam(teamId, skipDispatch = false, isReconnect =
}
}
if (!shouldShowLegacySidebar(state)) {
await dispatch(fetchMyCategories(teamId));
}
if (data.channels) {
actions.push({
type: ChannelTypes.RECEIVED_MY_CHANNELS_WITH_MEMBERS,

View File

@@ -166,6 +166,12 @@ describe('Actions.Views.Channel', () => {
[currentTeamId]: {},
},
},
general: {
config: {
EnableLegacySidebar: 'true',
},
serverVersion: '5.12.0',
},
},
};
@@ -174,7 +180,7 @@ describe('Actions.Views.Channel', () => {
channelSelectors.getCurrentChannelId = jest.fn(() => currentChannelId);
channelSelectors.getMyChannelMember = jest.fn(() => ({data: {member: {}}}));
const appChannelSelectors = require('app/selectors/channel');
const appChannelSelectors = require('@selectors/channel');
const getChannelReachableOriginal = appChannelSelectors.getChannelReachable;
appChannelSelectors.getChannelReachable = jest.fn(() => true);

View File

@@ -24,7 +24,6 @@ export function executeCommand(message: string, channelId: string, rootId: strin
channel_id: channelId,
team_id: teamId,
root_id: rootId,
parent_id: rootId,
};
let msg = message;
@@ -40,7 +39,7 @@ export function executeCommand(message: string, channelId: string, rootId: strin
const appsAreEnabled = appsEnabled(state);
if (appsAreEnabled) {
const parser = new AppCommandParser({dispatch, getState}, intl, args.channel_id, args.root_id);
const parser = new AppCommandParser({dispatch, getState}, intl, args.channel_id, args.team_id, args.root_id);
if (parser.isAppCommand(msg)) {
const {call, errorMessage} = await parser.composeCallFromCommand(msg);
const createErrorMessage = (errMessage: string) => {
@@ -67,8 +66,14 @@ export function executeCommand(message: string, channelId: string, rootId: strin
}
return {data: {}};
case AppCallResponseTypes.FORM:
return {data: {
form: callResp.form,
call,
}};
case AppCallResponseTypes.NAVIGATE:
return {data: {}};
return {data: {
goto_location: callResp.navigate_to_url,
}};
default:
return createErrorMessage(intl.formatMessage({
id: 'apps.error.responses.unknown_type',

View File

@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {addChannelToCategory} from '@mm-redux/actions/channel_categories';
import {createChannel} from '@mm-redux/actions/channels';
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
@@ -19,7 +20,7 @@ export function generateChannelNameFromDisplayName(displayName) {
return name;
}
export function handleCreateChannel(displayName, purpose, header, type) {
export function handleCreateChannel(displayName, purpose, header, type, categoryId) {
return async (dispatch, getState) => {
const state = getState();
const currentUserId = getCurrentUserId(state);
@@ -37,6 +38,10 @@ export function handleCreateChannel(displayName, purpose, header, type) {
if (data && data.id) {
dispatch(setChannelDisplayName(displayName));
dispatch(handleSelectChannel(data.id));
if (categoryId) {
dispatch(addChannelToCategory(categoryId, data.id));
}
}
};
}

View File

@@ -40,7 +40,6 @@ export function sendEphemeralPost(message, channelId = '', parentId = '', userId
create_at: timestamp,
update_at: timestamp,
root_id: parentId,
parent_id: parentId,
props: {},
};
@@ -62,7 +61,6 @@ export function sendAddToChannelEphemeralPost(user, addedUsername, message, chan
create_at: timestamp,
update_at: timestamp,
root_id: postRootId,
parent_id: postRootId,
props: {
username: user.username,
addedUsername,

View File

@@ -8,7 +8,7 @@ import {NavigationTypes, ViewTypes} from '@constants';
import {ChannelTypes, GeneralTypes, TeamTypes} from '@mm-redux/action_types';
import {getChannelAndMyMember} from '@mm-redux/actions/channels';
import {getDataRetentionPolicy} from '@mm-redux/actions/general';
import {receivedNewPost} from '@mm-redux/actions/posts';
import {receivedNewPost, selectPost} from '@mm-redux/actions/posts';
import {getMyTeams, getMyTeamMembers, getMyTeamUnreads} from '@mm-redux/actions/teams';
import {General} from '@mm-redux/constants';
import {isCollapsedThreadsEnabled} from '@mm-redux/selectors/entities/preferences';
@@ -97,7 +97,12 @@ export function loadFromPushNotification(notification, isInitialNotification) {
}
dispatch(handleSelectTeamAndChannel(teamId, channelId));
dispatch(selectPost(''));
const {root_id: rootId} = notification.payload || {};
if (isCollapsedThreadsEnabled(state) && rootId) {
dispatch(selectPost(rootId));
}
return {data: true};
};
}

View File

@@ -3,11 +3,9 @@
import moment from 'moment-timezone';
import {Client4} from '@client/rest';
import PushNotifications from '@init/push_notifications';
import {getSessions} from '@mm-redux/actions/users';
import {getConfig} from '@mm-redux/selectors/entities/general';
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
const sortByNewest = (a, b) => {
if (a.create_at > b.create_at) {
@@ -23,7 +21,7 @@ export function scheduleExpiredNotification(intl) {
const {currentUserId} = state.entities.users;
const config = getConfig(state);
if (isMinimumServerVersion(Client4.serverVersion, 5, 24) && config.ExtendSessionLengthWithActivity === 'true') {
if (config.ExtendSessionLengthWithActivity === 'true') {
PushNotifications.cancelAllLocalNotifications();
return;
}

View File

@@ -1,7 +1,8 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {fetchAppBindings} from '@mm-redux/actions/apps';
import {fetchAppBindings, fetchThreadAppBindings} from '@mm-redux/actions/apps';
import {getThreadAppsBindingsChannelId} from '@mm-redux/selectors/entities/apps';
import {getCurrentChannelId} from '@mm-redux/selectors/entities/common';
import {getCurrentUserId} from '@mm-redux/selectors/entities/users';
import {ActionResult, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
@@ -10,9 +11,17 @@ import {appsEnabled} from '@utils/apps';
export function handleRefreshAppsBindings() {
return (dispatch: DispatchFunc, getState: GetStateFunc): ActionResult => {
const state = getState();
if (appsEnabled(state)) {
dispatch(fetchAppBindings(getCurrentUserId(state), getCurrentChannelId(state)));
if (!appsEnabled(state)) {
return {data: true};
}
dispatch(fetchAppBindings(getCurrentUserId(state), getCurrentChannelId(state)));
const threadChannelID = getThreadAppsBindingsChannelId(state);
if (threadChannelID) {
dispatch(fetchThreadAppBindings(getCurrentUserId(state), threadChannelID));
}
return {data: true};
};
}

View File

@@ -0,0 +1,67 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {debounce} from 'underscore';
import {fetchMyCategories, receivedCategoryOrder} from '@mm-redux/actions/channel_categories';
import {getCurrentTeamId} from '@mm-redux/selectors/entities/teams';
import {ActionResult, DispatchFunc, GetStateFunc} from '@mm-redux/types/actions';
import {WebSocketMessage} from '@mm-redux/types/websocket';
const fetchCats = debounce((dispatch: DispatchFunc, teamId: string) => dispatch(fetchMyCategories(teamId)), 1000);
export function handleSidebarCategoryCreated(msg: WebSocketMessage) {
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
const state = getState();
const currentTeamId = getCurrentTeamId(state);
if (msg.broadcast.team_id !== currentTeamId) {
// The new category will be loaded when we switch teams.
return {data: false};
}
// Fetch all categories, including ones that weren't explicitly updated, in case any other categories had channels
// moved out of them.
dispatch(fetchMyCategories(msg.broadcast.team_id));
return {data: true};
};
}
export function handleSidebarCategoryUpdated(msg: WebSocketMessage) {
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
const state = getState();
if (msg.broadcast.team_id !== getCurrentTeamId(state)) {
// The updated categories will be loaded when we switch teams.
return {data: false};
}
// Fetch all categories in case any other categories had channels moved out of them.
// dispatch(fetchMyCategories(msg.broadcast.team_id));
fetchCats(dispatch, msg.broadcast.team_id);
return {data: true};
};
}
export function handleSidebarCategoryDeleted(msg: WebSocketMessage) {
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
const state = getState();
if (msg.broadcast.team_id !== getCurrentTeamId(state)) {
// The category will be removed when we switch teams.
return {data: false};
}
// Fetch all categories since any channels that were in the deleted category were moved to other categories.
dispatch(fetchMyCategories(msg.broadcast.team_id));
return {data: true};
};
}
export function handleSidebarCategoryOrderUpdated(msg: WebSocketMessage) {
return receivedCategoryOrder(msg.broadcast.team_id, msg.data.order);
}

View File

@@ -36,7 +36,7 @@ describe('Websocket Chanel Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});

View File

@@ -6,6 +6,7 @@ import {loadChannelsForTeam} from '@actions/views/channel';
import {Client4} from '@client/rest';
import {WebsocketEvents} from '@constants';
import {ChannelTypes, TeamTypes, RoleTypes} from '@mm-redux/action_types';
import {addChannelToInitialCategory} from '@mm-redux/actions/channel_categories';
import {markChannelAsRead} from '@mm-redux/actions/channels';
import {General} from '@mm-redux/constants';
import {
@@ -22,6 +23,7 @@ import {ActionResult, DispatchFunc, GenericAction, GetStateFunc, batchActions} f
import {WebSocketMessage} from '@mm-redux/types/websocket';
import {getChannelByName} from '@mm-redux/utils/channel_utils';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {shouldShowLegacySidebar} from '@utils/categories';
export function handleChannelConvertedEvent(msg: WebSocketMessage) {
return (dispatch: DispatchFunc, getState: GetStateFunc): ActionResult => {
@@ -47,12 +49,9 @@ export function handleChannelCreatedEvent(msg: WebSocketMessage) {
const currentTeamId = getCurrentTeamId(state);
if (teamId === currentTeamId && !channels[channelId]) {
const channelActions = await fetchChannelAndMyMember(msg.broadcast.channel_id);
if (channelActions.length) {
dispatch(batchActions(channelActions, 'BATCH_WS_CHANNEL_CREATED'));
}
return dispatch(fetchChannelAndAddToSidebar(msg.broadcast.channel_id, 'BATCH_WS_CHANNEL_CREATED'));
}
return {data: true};
return {data: false};
};
}
@@ -118,11 +117,7 @@ export function handleChannelMemberUpdatedEvent(msg: WebSocketMessage) {
export function handleChannelSchemeUpdatedEvent(msg: WebSocketMessage) {
return async (dispatch: DispatchFunc): Promise<ActionResult> => {
const channelActions = await fetchChannelAndMyMember(msg.broadcast.channel_id);
if (channelActions.length) {
dispatch(batchActions(channelActions, 'BATCH_WS_SCHEME_UPDATE'));
}
return {data: true};
return dispatch(fetchChannelAndAddToSidebar(msg.broadcast.channel_id, 'BATCH_WS_SCHEME_UPDATE'));
};
}
@@ -200,11 +195,7 @@ export function handleChannelViewedEvent(msg: WebSocketMessage) {
export function handleDirectAddedEvent(msg: WebSocketMessage) {
return async (dispatch: DispatchFunc): Promise<ActionResult> => {
const channelActions = await fetchChannelAndMyMember(msg.broadcast.channel_id);
if (channelActions.length) {
dispatch(batchActions(channelActions, 'BATCH_WS_DM_ADDED'));
}
return {data: true};
return dispatch(fetchChannelAndAddToSidebar(msg.broadcast.channel_id, 'BATCH_WS_DM_ADDED'));
};
}
@@ -236,3 +227,23 @@ export function handleUpdateMemberRoleEvent(msg: WebSocketMessage) {
};
}
export function fetchChannelAndAddToSidebar(channelId: string, type?: string) {
return async (dispatch: DispatchFunc, getState: GetStateFunc): Promise<ActionResult> => {
const channelActions = await fetchChannelAndMyMember(channelId);
let channel;
if (channelActions.length) {
channel = channelActions.find((el) => el.type === ChannelTypes.RECEIVED_CHANNEL);
dispatch(batchActions(channelActions, type));
}
const state = getState();
if (channel && !shouldShowLegacySidebar(state)) {
dispatch(addChannelToInitialCategory(channel.data));
return {data: true};
}
return {data: false};
};
}

View File

@@ -28,7 +28,7 @@ describe('Websocket General Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});

View File

@@ -22,12 +22,12 @@ import {GlobalState} from '@mm-redux/types/store';
import {TeamMembership} from '@mm-redux/types/teams';
import {WebSocketMessage} from '@mm-redux/types/websocket';
import EventEmitter from '@mm-redux/utils/event_emitter';
import {isMinimumServerVersion} from '@mm-redux/utils/helpers';
import {removeUserFromList} from '@mm-redux/utils/user_utils';
import {getChannelSinceValue} from '@utils/channels';
import websocketClient from '@websocket';
import {handleRefreshAppsBindings} from './apps';
import {handleSidebarCategoryCreated, handleSidebarCategoryDeleted, handleSidebarCategoryOrderUpdated, handleSidebarCategoryUpdated} from './categories';
import {
handleChannelConvertedEvent,
handleChannelCreatedEvent,
@@ -99,7 +99,7 @@ export function doFirstConnect(now: number) {
const {lastDisconnectAt} = state.websocket;
const actions: Array<GenericAction> = [wsConnected(now)];
if (isMinimumServerVersion(Client4.getServerVersion(), 5, 14) && lastDisconnectAt) {
if (lastDisconnectAt) {
const currentUserId = getCurrentUserId(state);
const users = getUsers(state);
const userIds = Object.keys(users);
@@ -220,7 +220,7 @@ export function doReconnect(now: number) {
});
}
if (isMinimumServerVersion(Client4.getServerVersion(), 5, 14) && lastDisconnectAt) {
if (lastDisconnectAt) {
const userIds = Object.keys(users);
const userUpdates = await Client4.getProfilesByIds(userIds, {since: lastDisconnectAt});
@@ -409,9 +409,16 @@ function handleEvent(msg: WebSocketMessage) {
return dispatch(handleThreadReadChanged(msg));
case WebsocketEvents.THREAD_FOLLOW_CHANGED:
return dispatch(handleThreadFollowChanged(msg));
case WebsocketEvents.APPS_FRAMEWORK_REFRESH_BINDINGS: {
case WebsocketEvents.APPS_FRAMEWORK_REFRESH_BINDINGS:
return dispatch(handleRefreshAppsBindings());
}
case WebsocketEvents.SIDEBAR_CATEGORY_CREATED:
return dispatch(handleSidebarCategoryCreated(msg));
case WebsocketEvents.SIDEBAR_CATEGORY_UPDATED:
return dispatch(handleSidebarCategoryUpdated(msg));
case WebsocketEvents.SIDEBAR_CATEGORY_DELETED:
return dispatch(handleSidebarCategoryDeleted(msg));
case WebsocketEvents.SIDEBAR_CATEGORY_ORDER_UPDATED:
return dispatch(handleSidebarCategoryOrderUpdated(msg));
}
return {data: true};

View File

@@ -26,7 +26,7 @@ describe('Websocket Integration Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});

View File

@@ -34,7 +34,7 @@ describe('Websocket Post Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});
@@ -42,7 +42,7 @@ describe('Websocket Post Events', () => {
it('Websocket Handle New Post if post does not exist', async () => {
PostSelectors.getPost = jest.fn();
const channelId = TestHelper.basicChannel.id;
const message = JSON.stringify({event: WebsocketEvents.POSTED, data: {channel_display_name: TestHelper.basicChannel.display_name, channel_name: TestHelper.basicChannel.name, channel_type: 'O', post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w", "create_at": 1508245311774, "update_at": 1508245311774, "edit_at": 0, "delete_at": 0, "is_pinned": false, "user_id": "${TestHelper.basicUser.id}", "channel_id": "${channelId}", "root_id": "", "parent_id": "", "original_id": "", "message": "Unit Test", "type": "", "props": {}, "hashtags": "", "pending_post_id": "t36kso9nwtdhbm8dbkd6g4eeby: 1508245311749"}`, sender_name: TestHelper.basicUser.username, team_id: TestHelper.basicTeam.id}, broadcast: {omit_users: null, user_id: '', channel_id: channelId, team_id: ''}, seq: 2});
const message = JSON.stringify({event: WebsocketEvents.POSTED, data: {channel_display_name: TestHelper.basicChannel.display_name, channel_name: TestHelper.basicChannel.name, channel_type: 'O', post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w", "create_at": 1508245311774, "update_at": 1508245311774, "edit_at": 0, "delete_at": 0, "is_pinned": false, "user_id": "${TestHelper.basicUser.id}", "channel_id": "${channelId}", "root_id": "", "original_id": "", "message": "Unit Test", "type": "", "props": {}, "hashtags": "", "pending_post_id": "t36kso9nwtdhbm8dbkd6g4eeby: 1508245311749"}`, sender_name: TestHelper.basicUser.username, team_id: TestHelper.basicTeam.id}, broadcast: {omit_users: null, user_id: '', channel_id: channelId, team_id: ''}, seq: 2});
nock(Client4.getBaseRoute()).
post('/users/ids').
@@ -62,7 +62,7 @@ describe('Websocket Post Events', () => {
// Mock that post does not exist and check it is added
PostSelectors.getPost.mockReturnValueOnce(false);
mockServer.emit('message', message);
await TestHelper.wait(100);
await TestHelper.wait(300);
entities = store.getState().entities;
posts = entities.posts.posts;
const postId = Object.keys(posts)[0];
@@ -75,7 +75,7 @@ describe('Websocket Post Events', () => {
const emit = jest.spyOn(EventEmitter, 'emit');
const currentChannelId = TestHelper.generateId();
const otherChannelId = TestHelper.generateId();
const messageFor = (channelId) => ({event: WebsocketEvents.POSTED, data: {channel_display_name: TestHelper.basicChannel.display_name, channel_name: TestHelper.basicChannel.name, channel_type: 'O', post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w", "create_at": 1508245311774, "update_at": 1508245311774, "edit_at": 0, "delete_at": 0, "is_pinned": false, "user_id": "${TestHelper.basicUser.id}", "channel_id": "${channelId}", "root_id": "", "parent_id": "", "original_id": "", "message": "Unit Test", "type": "", "props": {}, "hashtags": "", "pending_post_id": "t36kso9nwtdhbm8dbkd6g4eeby: 1508245311749"}`, sender_name: TestHelper.basicUser.username, team_id: TestHelper.basicTeam.id}, broadcast: {omit_users: null, user_id: '', channel_id: channelId, team_id: ''}, seq: 2});
const messageFor = (channelId) => ({event: WebsocketEvents.POSTED, data: {channel_display_name: TestHelper.basicChannel.display_name, channel_name: TestHelper.basicChannel.name, channel_type: 'O', post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w", "create_at": 1508245311774, "update_at": 1508245311774, "edit_at": 0, "delete_at": 0, "is_pinned": false, "user_id": "${TestHelper.basicUser.id}", "channel_id": "${channelId}", "root_id": "", "original_id": "", "message": "Unit Test", "type": "", "props": {}, "hashtags": "", "pending_post_id": "t36kso9nwtdhbm8dbkd6g4eeby: 1508245311749"}`, sender_name: TestHelper.basicUser.username, team_id: TestHelper.basicTeam.id}, broadcast: {omit_users: null, user_id: '', channel_id: channelId, team_id: ''}, seq: 2});
await store.dispatch(ChannelActions.selectChannel(currentChannelId));
await TestHelper.wait(100);
@@ -125,7 +125,7 @@ describe('Websocket Post Events', () => {
channel_display_name: TestHelper.basicChannel.display_name,
channel_name: TestHelper.basicChannel.name,
channel_type: 'O',
post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w", "create_at": 1508245311774, "update_at": 1508245311774, "edit_at": 0, "delete_at": 0, "is_pinned": false, "user_id": "${userId}", "channel_id": "${channelId}", "root_id": "", "parent_id": "", "original_id": "", "message": "Unit Test", "type": "", "props": {}, "hashtags": "", "pending_post_id": "t36kso9nwtdhbm8dbkd6g4eeby: 1508245311749"}`,
post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w", "create_at": 1508245311774, "update_at": 1508245311774, "edit_at": 0, "delete_at": 0, "is_pinned": false, "user_id": "${userId}", "channel_id": "${channelId}", "root_id": "", "original_id": "", "message": "Unit Test", "type": "", "props": {}, "hashtags": "", "pending_post_id": "t36kso9nwtdhbm8dbkd6g4eeby: 1508245311749"}`,
sender_name: TestHelper.basicUser.username,
team_id: TestHelper.basicTeam.id,
},
@@ -146,7 +146,7 @@ describe('Websocket Post Events', () => {
it('Websocket Handle Post Edited', async () => {
const post = {id: '71k8gz5ompbpfkrzaxzodffj8w'};
mockServer.emit('message', JSON.stringify({event: WebsocketEvents.POST_EDITED, data: {post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w","create_at": 1508245311774,"update_at": 1585236976007,"edit_at": 1585236976007,"delete_at": 0,"is_pinned": false,"user_id": "${TestHelper.basicUser.id}","channel_id": "${TestHelper.basicChannel.id}","root_id": "","parent_id": "","original_id": "","message": "Unit Test (edited)","type": "","props": {},"hashtags": "","pending_post_id": ""}`}, broadcast: {omit_users: null, user_id: '', channel_id: '18k9ffsuci8xxm7ak68zfdyrce', team_id: ''}, seq: 2}));
mockServer.emit('message', JSON.stringify({event: WebsocketEvents.POST_EDITED, data: {post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w","create_at": 1508245311774,"update_at": 1585236976007,"edit_at": 1585236976007,"delete_at": 0,"is_pinned": false,"user_id": "${TestHelper.basicUser.id}","channel_id": "${TestHelper.basicChannel.id}","root_id": "","original_id": "","message": "Unit Test (edited)","type": "","props": {},"hashtags": "","pending_post_id": ""}`}, broadcast: {omit_users: null, user_id: '', channel_id: '18k9ffsuci8xxm7ak68zfdyrce', team_id: ''}, seq: 2}));
await TestHelper.wait(300);
@@ -162,7 +162,7 @@ describe('Websocket Post Events', () => {
post.id = '71k8gz5ompbpfkrzaxzodffj8w';
store.dispatch(PostActions.receivedPost(post));
mockServer.emit('message', JSON.stringify({event: WebsocketEvents.POST_DELETED, data: {post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w","create_at": 1508245311774,"update_at": 1508247709215,"edit_at": 1508247709215,"delete_at": 0,"is_pinned": false,"user_id": "${TestHelper.basicUser.id}","channel_id": "${post.channel_id}","root_id": "","parent_id": "","original_id": "","message": "Unit Test","type": "","props": {},"hashtags": "","pending_post_id": ""}`}, broadcast: {omit_users: null, user_id: '', channel_id: '18k9ffsuci8xxm7ak68zfdyrce', team_id: ''}, seq: 7}));
mockServer.emit('message', JSON.stringify({event: WebsocketEvents.POST_DELETED, data: {post: `{"id": "71k8gz5ompbpfkrzaxzodffj8w","create_at": 1508245311774,"update_at": 1508247709215,"edit_at": 1508247709215,"delete_at": 0,"is_pinned": false,"user_id": "${TestHelper.basicUser.id}","channel_id": "${post.channel_id}","root_id": "","original_id": "","message": "Unit Test","type": "","props": {},"hashtags": "","pending_post_id": ""}`}, broadcast: {omit_users: null, user_id: '', channel_id: '18k9ffsuci8xxm7ak68zfdyrce', team_id: ''}, seq: 7}));
const entities = store.getState().entities;
const {posts} = entities.posts;

View File

@@ -26,7 +26,7 @@ describe('Websocket Reaction Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});

View File

@@ -35,7 +35,7 @@ describe('Websocket Team Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});

View File

@@ -33,7 +33,7 @@ describe('Websocket User Events', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});

View File

@@ -64,7 +64,7 @@ describe('Actions.Websocket', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
mockServer.stop();
await TestHelper.tearDown();
});
@@ -166,7 +166,7 @@ describe('Actions.Websocket doReconnect', () => {
});
afterAll(async () => {
Actions.close()();
Actions.close();
await TestHelper.tearDown();
});
@@ -373,7 +373,7 @@ describe('Actions.Websocket notVisibleUsersActions', () => {
const user4 = TestHelper.fakeUserWithId();
const user5 = TestHelper.fakeUserWithId();
it('should do nothing if the known users and the profiles list are the same', async () => {
it.skip('should do nothing if the known users and the profiles list are the same', async () => {
const profiles = {
[me.id]: me,
[user.id]: user,
@@ -397,7 +397,7 @@ describe('Actions.Websocket notVisibleUsersActions', () => {
expect(actions.length).toEqual(0);
});
it('should do nothing if there are known users in my memberships but not in the profiles list', async () => {
it.skip('should do nothing if there are known users in my memberships but not in the profiles list', async () => {
const profiles = {
[me.id]: me,
[user3.id]: user3,
@@ -419,7 +419,7 @@ describe('Actions.Websocket notVisibleUsersActions', () => {
expect(actions.length).toEqual(0);
});
it('should remove the users if there are unknown users in the profiles list', async () => {
it.skip('should remove the users if there are unknown users in the profiles list', async () => {
const profiles = {
[me.id]: me,
[user.id]: user,
@@ -450,32 +450,6 @@ describe('Actions.Websocket notVisibleUsersActions', () => {
expect(actions.length).toEqual(3);
expect(actions).toEqual(expectedAction);
});
it('should do nothing if the server version is less than 5.23', async () => {
const profiles = {
[me.id]: me,
[user.id]: user,
[user2.id]: user2,
[user3.id]: user3,
[user4.id]: user4,
[user5.id]: user5,
};
Client4.serverVersion = '5.22.0';
const state = {
entities: {
users: {
currentUserId: me.id,
profiles,
},
},
};
mockGetKnownUsersRequest([user.id, user3.id]);
const actions = await notVisibleUsersActions(state);
expect(actions.length).toEqual(0);
});
});
describe('Actions.Websocket handleUserTypingEvent', () => {
@@ -528,7 +502,7 @@ describe('Actions.Websocket handleUserTypingEvent', () => {
const expectedActionsTypes = [
WebsocketEvents.TYPING,
UserTypes.RECEIVED_STATUSES,
'BATCHING_REDUCER.BATCH',
];
await testStore.dispatch(Actions.handleUserTypingEvent(msg));

View File

@@ -2,6 +2,7 @@
// See LICENSE.txt for license information.
import {analytics} from '@init/analytics';
import {ChannelCategory, OrderedChannelCategories} from '@mm-redux/types/channel_categories';
import {Channel, ChannelMemberCountByGroup, ChannelMembership, ChannelNotifyProps, ChannelStats} from '@mm-redux/types/channels';
import {buildQueryString} from '@mm-redux/utils/helpers';
@@ -40,6 +41,12 @@ export interface ClientChannelsMix {
autocompleteChannelsForSearch: (teamId: string, name: string) => Promise<Channel[]>;
searchChannels: (teamId: string, term: string) => Promise<Channel[]>;
searchArchivedChannels: (teamId: string, term: string) => Promise<Channel[]>;
// Categories
getChannelCategories: (userId: string, teamId: string) => Promise<OrderedChannelCategories>;
getChannelCategory: () => Promise<ChannelCategory>;
updateChannelCategory: (userId: string, teamId: string, category: ChannelCategory) => Promise<OrderedChannelCategories>;
updateChannelCategories: (userId: string, teamId: string, categories: ChannelCategory[]) => Promise<OrderedChannelCategories>;
}
const ClientChannels = (superclass: any) => class extends superclass {
@@ -306,6 +313,39 @@ const ClientChannels = (superclass: any) => class extends superclass {
{method: 'post', body: JSON.stringify({term})},
);
};
// Channel Category Routes
getChannelCategoriesRoute(userId: string, teamId: string) {
return `${this.getUserRoute('me')}/teams/${teamId}/channels/categories`;
}
getChannelCategories = async (userId: string, teamId: string) => {
return this.doFetch(
`${this.getChannelCategoriesRoute(userId, teamId)}`,
{method: 'get'},
);
};
getChannelCategory = async (userId: string, teamId: string, categoryId: string) => {
return this.doFetch(
`${this.getChannelCategoriesRoute(userId, teamId)}/${categoryId}`,
{method: 'get'},
);
};
updateChannelCategory = (userId: string, teamId: string, category: ChannelCategory) => {
return this.doFetch(
`${this.getChannelCategoriesRoute(userId, teamId)}/${category.id}`,
{method: 'put', body: JSON.stringify(category)},
);
};
updateChannelCategories = (userId: string, teamId: string, categories: ChannelCategory[]) => {
return this.doFetch(
`${this.getChannelCategoriesRoute(userId, teamId)}`,
{method: 'put', body: JSON.stringify(categories)},
);
};
};
export default ClientChannels;

View File

@@ -4,7 +4,7 @@
import {analytics} from '@init/analytics';
import {FileInfo} from '@mm-redux/types/files';
import {Post} from '@mm-redux/types/posts';
import {buildQueryString} from '@mm-redux/utils/helpers';
import {buildQueryString, isMinimumServerVersion} from '@mm-redux/utils/helpers';
import {PER_PAGE_DEFAULT} from './constants';
@@ -126,9 +126,16 @@ const ClientPosts = (superclass: any) => class extends superclass {
);
};
getUserThreads = async (userId: string, teamId: string, before = '', after = '', pageSize = PER_PAGE_DEFAULT, extended = false, deleted = false, unread = false, since = 0) => {
getUserThreads = async (userId: string, teamId: string, before = '', after = '', perPage = PER_PAGE_DEFAULT, extended = false, deleted = false, unread = false, since = 0) => {
const serverVersion = this.getServerVersion();
let queryStringObj;
if (isMinimumServerVersion(serverVersion, 6, 0)) {
queryStringObj = {before, after, per_page: perPage, extended, deleted, unread, since};
} else {
queryStringObj = {before, after, pageSize: perPage, extended, deleted, unread, since};
}
return this.doFetch(
`${this.getUserThreadsRoute(userId, teamId)}${buildQueryString({before, after, pageSize, extended, deleted, unread, since})}`,
`${this.getUserThreadsRoute(userId, teamId)}${buildQueryString(queryStringObj)}`,
{method: 'get'},
);
};
@@ -243,8 +250,13 @@ const ClientPosts = (superclass: any) => class extends superclass {
searchPostsWithParams = async (teamId: string, params: any) => {
analytics.trackAPI('api_posts_search', {team_id: teamId});
let route = `${this.getPostsRoute()}/search`;
if (teamId) {
route = `${this.getTeamRoute(teamId)}/posts/search`;
}
return this.doFetch(
`${this.getTeamRoute(teamId)}/posts/search`,
route,
{method: 'post', body: JSON.stringify(params)},
);
};

View File

@@ -4,7 +4,7 @@
import {analytics} from '@init/analytics';
import {General} from '@mm-redux/constants';
import {UserCustomStatus, UserProfile, UserStatus} from '@mm-redux/types/users';
import {buildQueryString, isMinimumServerVersion} from '@mm-redux/utils/helpers';
import {buildQueryString} from '@mm-redux/utils/helpers';
import {PER_PAGE_DEFAULT} from './constants';
@@ -104,7 +104,6 @@ const ClientUsers = (superclass: any) => class extends superclass {
getKnownUsers = async () => {
analytics.trackAPI('api_get_known_users');
return this.doFetch(
`${this.getUsersRoute()}/known`,
{method: 'get'},
@@ -255,13 +254,7 @@ const ClientUsers = (superclass: any) => class extends superclass {
getProfilesInChannel = async (channelId: string, page = 0, perPage = PER_PAGE_DEFAULT, sort = '') => {
analytics.trackAPI('api_profiles_get_in_channel', {channel_id: channelId});
const serverVersion = this.getServerVersion();
let queryStringObj;
if (isMinimumServerVersion(serverVersion, 4, 7)) {
queryStringObj = {in_channel: channelId, page, per_page: perPage, sort};
} else {
queryStringObj = {in_channel: channelId, page, per_page: perPage};
}
const queryStringObj = {in_channel: channelId, page, per_page: perPage, sort};
return this.doFetch(
`${this.getUsersRoute()}${buildQueryString(queryStringObj)}`,
{method: 'get'},

View File

@@ -17,31 +17,31 @@ exports[`profile_picture_button should match snapshot 1`] = `
maxFileSize={20971520}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"awayIndicator": "#ffbc1f",
"buttonBg": "#1c58d9",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"centerChannelColor": "#3f4350",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"dndIndicator": "#d24b4e",
"errorTextColor": "#d24b4e",
"linkColor": "#386fe5",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"mentionColor": "#1e325c",
"mentionHighlightBg": "#ffd470",
"mentionHighlightLink": "#1b1d22",
"newMessageSeparator": "#cc8f00",
"onlineIndicator": "#3db887",
"sidebarBg": "#1e325c",
"sidebarHeaderBg": "#192a4d",
"sidebarHeaderTextColor": "#ffffff",
"sidebarTeamBarBg": "#14213e",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveBorder": "#5d89ea",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarTextHoverBg": "#28427b",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
"type": "Denim",
}
}
uploadFiles={[MockFunction]}

View File

@@ -36,31 +36,31 @@ exports[`AnnouncementBanner should match snapshot 1`] = `
}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"awayIndicator": "#ffbc1f",
"buttonBg": "#1c58d9",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"centerChannelColor": "#3f4350",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"dndIndicator": "#d24b4e",
"errorTextColor": "#d24b4e",
"linkColor": "#386fe5",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"mentionColor": "#1e325c",
"mentionHighlightBg": "#ffd470",
"mentionHighlightLink": "#1b1d22",
"newMessageSeparator": "#cc8f00",
"onlineIndicator": "#3db887",
"sidebarBg": "#1e325c",
"sidebarHeaderBg": "#192a4d",
"sidebarHeaderTextColor": "#ffffff",
"sidebarTeamBarBg": "#14213e",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveBorder": "#5d89ea",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarTextHoverBg": "#28427b",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
"type": "Denim",
}
}
/>
@@ -102,31 +102,31 @@ exports[`AnnouncementBanner should match snapshot 2`] = `
}
theme={
Object {
"awayIndicator": "#ffbc42",
"buttonBg": "#166de0",
"awayIndicator": "#ffbc1f",
"buttonBg": "#1c58d9",
"buttonColor": "#ffffff",
"centerChannelBg": "#ffffff",
"centerChannelColor": "#3d3c40",
"centerChannelColor": "#3f4350",
"codeTheme": "github",
"dndIndicator": "#f74343",
"errorTextColor": "#fd5960",
"linkColor": "#2389d7",
"dndIndicator": "#d24b4e",
"errorTextColor": "#d24b4e",
"linkColor": "#386fe5",
"mentionBg": "#ffffff",
"mentionBj": "#ffffff",
"mentionColor": "#145dbf",
"mentionHighlightBg": "#ffe577",
"mentionHighlightLink": "#166de0",
"newMessageSeparator": "#ff8800",
"onlineIndicator": "#06d6a0",
"sidebarBg": "#145dbf",
"sidebarHeaderBg": "#1153ab",
"mentionColor": "#1e325c",
"mentionHighlightBg": "#ffd470",
"mentionHighlightLink": "#1b1d22",
"newMessageSeparator": "#cc8f00",
"onlineIndicator": "#3db887",
"sidebarBg": "#1e325c",
"sidebarHeaderBg": "#192a4d",
"sidebarHeaderTextColor": "#ffffff",
"sidebarTeamBarBg": "#14213e",
"sidebarText": "#ffffff",
"sidebarTextActiveBorder": "#579eff",
"sidebarTextActiveBorder": "#5d89ea",
"sidebarTextActiveColor": "#ffffff",
"sidebarTextHoverBg": "#4578bf",
"sidebarTextHoverBg": "#28427b",
"sidebarUnreadText": "#ffffff",
"type": "Mattermost",
"type": "Denim",
}
}
/>

View File

@@ -17,7 +17,7 @@ describe('AnnouncementBanner', () => {
bannerEnabled: true,
bannerText: 'Banner Text',
bannerTextColor: '#fff',
theme: Preferences.THEMES.default,
theme: Preferences.THEMES.denim,
};
test('should match snapshot', () => {

Some files were not shown because too many files have changed in this diff Show More