Popular New Releases in Chat
taro
chore(release): publish 3.4.7
python-telegram-bot
v13.11
tinker
litemall
v1.8.0
vant-weapp
v1.10.2
Popular Libraries in Chat
by dcloudio javascript
36431 Apache-2.0
uni-app 是使用 Vue 语法开发小程序、H5、App的统一框架
by NervJS typescript
30875 MIT
开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
by littlecodersh python
21699 NOASSERTION
A complete and graceful API for Wechat. 微信个人号接口、微信机器人及命令行微信,三十行即可自定义个人号机器人。
by python-telegram-bot python
18256 NOASSERTION
We have made you a wrapper you can't refuse
by Tencent java
16260 NOASSERTION
Tinker is a hot-fix solution library for Android, it supports dex, library and resources update without reinstall apk.
by linlinjava java
16176 MIT
又一个小商城。litemall = Spring Boot后端 + Vue管理员前端 + 微信小程序用户前端 + Vue用户移动端
by Tencent c++
16100 NOASSERTION
Mars is a cross-platform network component developed by WeChat.
by youzan javascript
15795 MIT
轻量、可靠的小程序 UI 组件库
by zulip python
15620 Apache-2.0
Zulip server and web app—powerful open source team chat
Trending New libraries in Chat
by alexeygrigorev html
5065 CC-BY-4.0
Data science interview questions and answers
by orkestral javascript
3775 Apache-2.0
Venom is the most complete javascript library for Whatsapp, 100% Open Source.
by fosscord javascript
3576 AGPL-3.0
Fosscord is a free open source selfhostable discord compatible communication platform
by ottomated typescript
3159 GPL-3.0
Free, open, Among Us Proximity Chat
by raycast shell
2351 MIT
Script Commands let you tailor Raycast to your needs. Think of them as little productivity boosts throughout your day.
by Pycord-Development python
1944 MIT
Pycord, a maintained fork of discord.py, is a python wrapper for the Discord API
by stypr python
1669 MIT
Clubhouse API written in Python. Standalone client included. For reference and education purposes only.
by nonebot python
1525 MIT
跨平台 Python 异步机器人框架 / Asynchronous multi-platform robot framework written in Python
by nining377 c
1517 MIT
杜比大喇叭的β版迎来了重大的革新,合并了UnblockMusic Pro的所有功能且更加强大,同时UnblockMusicPro_Xposed项目将会停止维护,让我们欢送这位老朋友!
Top Authors in Chat
1
86 Libraries
1233
2
26 Libraries
14368
3
21 Libraries
3329
4
20 Libraries
1218
5
19 Libraries
1947
6
16 Libraries
795
7
14 Libraries
15203
8
14 Libraries
3162
9
14 Libraries
213
10
14 Libraries
1580
1
86 Libraries
1233
2
26 Libraries
14368
3
21 Libraries
3329
4
20 Libraries
1218
5
19 Libraries
1947
6
16 Libraries
795
7
14 Libraries
15203
8
14 Libraries
3162
9
14 Libraries
213
10
14 Libraries
1580
Trending Kits in Chat
Most Python Discord API libraries offer various features, making it easier to develop Discord bots and interact with the Discord API. Most Python Discord API libraries offer an effortless way of creating and managing bots on the Discord Platform. These libraries often offer functionality for handling events like a user joining a server, a reaction added to a message, or a message received.
These libraries offer effortless ways to handle commands from the Discord server users. It can handle audio and voice functionalities, like streaming video, joining voice channels, and more. These support Discord’s new slash commands that offer an easy-to-use interface for users to interact with bots. It has a built-in caching mechanism for reducing the number of API requests to Discord and improving its performance. It offers methods for easily making requests to the Discord API and handling responses. It supports Discord webhooks by letting bots send messages and interact with Discord outside a server.
Here is the list of the top 8 Python Discord API libraries that are handpicked to help developers:
discord.py:
- Is an easy-to-use, asynchronous-ready, modern, and feature-rich API wrapper for Discord written in Python.
- Offers a simple and intuitive API to build Discord bots, making it accessible for developers of all skill sets.
- Has robust support for audio and voice, like streaming audio, joining voice channels, and many more.
modmail:
- Is a Python library to build a moderation system within Discord servers.
- Allows users to contact server administration and moderators privately without having to share their messages publicly in a channel.
- Tracks user data like their conversation and messages history, making it easier for moderators to handle ongoing issues.
nextcord:
- Is a Python library to build Discord bots that are forked from the original discord.py.
- Offers similar functionality as discord.py with certain improvements and changes.
- Has support for Discord’s new slash commands that offers an easy-to-use for users to interact with bots.
hikari:
- Is a Python library to build Discord bots that aim to offer a modern and efficient API compared to other Python Discord libraries.
- Is designed with modern Python features like type hints and async/await.
- Is optimized for performance and uses asyncio for handling requests and events.
interactions.py:
- Is a Python library that is a highly extensible, complete feature, and easy-to-use bot framework for Discord.
- Our HTTP client implements preemptive rate limit avoidance, so your bot is guaranteed never to hit HTTP 429.
- Each HTTP request and Gateway event made is cached if needed, so you never have to save information yourself.
disnake:
- Is a fast, efficient, and modern Python library to build Discord bots, a fork of the discord.py library with many improvements.
- Is optimized for performance and uses asyncio to handle requests and events, making it one of the fastest Discord libraries.
- Discord’s components are supported in disnake, allowing more engaging and interactive bot experiences.
jishaku:
- Is a debugging and testing extension for Discord.py, a popular Python library for creating Discord bots.
- Offers various utilities for debugging and testing Discord.py applications, like an interactive shell for running code snippets and functionality and commands for inspecting the current state of the server and bot.
- Advanced error handling and reports with detailed information about the cause of errors and how to fix them.
Raid-Toolbox:
- A Python library is a big toolkit of raiding, token management, and spamming tools for Discord.
- Includes custom themes or skins, token checker, message spammer, and mass mentioner.
- Also includes DM spammer, Group DM spammer, image spammer, embed spammer, and Ascii spammer.
Here are some of the famous Nodejs WhatsApp API Libraries. These Libraries are used for Creating interactive bots, Creating chatbots, Sending automated messages, and Integrating with other applications.
Node.js WhatsApp API Libraries are libraries that allow developers to create applications and services that interact with the WhatsApp messaging service. These libraries provide access to the WhatsApp API, allowing developers to create custom tools and applications that communicate with WhatsApp users. These libraries can be used to build bots, create custom chat experiences, and more.
Let us look at these libraries in detail below.
whatsapp-web.js
- Auto-detection of incoming messages, allowing developers to respond quickly.
- Built-in media upload and download support.
- Built-in webhooks for automated responses.
Chat-API
- Allows developers to build applications that integrate with multiple messaging platforms.
- Provides support for multi-user chat rooms.
- Allows developers to receive notifications whenever messages are sent or received.
sulla
- Offers a wide range of analytics and reporting capabilities.
- Integrates with other third-party services, such as Slack.
- Powerful set of APIs for automating the WhatsApp messaging experience.
whats2api
- Full control over incoming messages.
- Event-driven notifications.
- Flexible API calls and built-in security features.
whatsapi
- Highly secure and provides end-to-end encryptions for all messages sent and received.
- Provides a comprehensive set of features for managing contacts, groups, and conversations.
- Allows developers to access and control the WhatsApp API directly from their applications.
wasapbot
- Easy-to-use platform that allows you to quickly build a WhatsApp bot without the need to write any code.
- Provides a user-friendly interface with a drag-and-drop editor to create sophisticated chatbots.
- Handle complex conversations and can work with multiple users at the same time.
whatbot
- Allows users to customize their conversations using a variety of built-in templates.
- Provides an intuitive interface to set up automated messages and bot responses.
- Ability to process incoming messages, and send and receive images and videos etc.
Django Calendar Libraries include Automating customer service, marketing, Creating chatbots, customer feedback, and Automating payments.
Python WhatsApp API libraries are libraries of code written in the Python programming language that can develop applications that interact with the WhatsApp messaging platform. These libraries typically enable developers to create tools, bots, and other programs to send and receive messages, process messages and integrate with other services and APIs.
Let us look at these libraries in detail.
yowsup
- Supports both the WhatsApp web and mobile platforms.
- Allows developers to send and receive messages, images, videos, and audio files.
- Supports group chats and broadcast messages.
whatsapp-framework
- Offers a powerful text-parsing feature that allows developers to parse incoming messages.
- Supports both synchronous and asynchronous messaging.
- Easy-to-use design helps developers quickly integrate its features into their applications.
PyWhatKit
- Built-in scheduler allows you to schedule messages to be sent at a later date and time.
- Simple, intuitive, and user-friendly API.
- Possible to read incoming messages and respond to them.
PyWhatsapp
- Offers a built-in event loop, which allows users to process incoming messages and react to them in real time.
- Highly flexible and can be used to create powerful custom WhatsApp bots.
- Supports media sending, which is unavailable in most other Python WhatsApp API libraries.
whatsapp-cli
- Command-line interface (CLI) tool allows users to interact directly with the WhatsApp API from their terminal.
- Many advanced features include group chats, file sharing, broadcast messages, and more.
- Built using the WhatsApp Web API, it is always up-to-date with the latest WhatsApp features.
whatsapp-api-client-python
- An automated setup process that makes it easy to get up and run quickly with the WhatsApp API.
- Supports both Python 2 and Python 3.
- Built-in error handling.
WhatsApp-Chat-Analyzer-API
- Used to generate visualizations of the conversations, such as word clouds, heatmaps, and network graphs.
- Provides a range of features for analyzing conversations, such as sentiment analysis, keyword extraction, and topic modeling.
- Open source and is available for free.
whatsapp-wrapper
- Provides a wrapper for the official WhatsApp API.
- Built-in webhook system.
- Provides robust API endpoints for creating, editing, and deleting conversations.
pywassap
- Offers a complete suite of APIs to interact with WhatsApp services.
- Highly customizable, allowing users to adjust the API to their specific needs.
- Offers a secure and reliable connection with WhatsApp’s servers.
Chat-API
- Automated message scheduling.
- File and media messaging.
- Easy integration with other apps and services.
FAQ
What is WhatsApp Cloud API Python?
WhatsApp API doesn’t directly interact with a “Cloud API” as other services do. It is typically hosted on the business’s servers. It allows them to send and receive messages through WhatsApp.
What is the WhatsApp Business API?
WhatsApp provides a Business API. It allows businesses API to provide a way for businesses to send messages to users. It helps receive messages from users and manage various aspects of business accounts.
WhatsApp Business API supports various programming languages, including Python. It allows developers to integrate WhatsApp messaging capabilities into their applications.
Is there a Python wrapper for WhatsApp?
WhatsApp is restrictive about third-party applications. It helps in interacting with their service to maintain user privacy and security. However, there have been community-driven projects and third-party libraries. It provides Python wrappers or APIs to interact with WhatsApp.
These might have limitations and may not be officially endorsed. However, it is crucial to be cautious when using such tools. It helps ensure compliance with WhatsApp’s terms of service.
What are the different types of WhatsApp messages?
WhatsApp supports various WhatsApp message types. It facilitates different forms of communication. Here are some common types of messages you can send and receive on WhatsApp:
- Text Messages
- Images and Videos
- Location Sharing
- Voice Messages
- Documents
- Stickers and Emojis
- Contacts
- Status Updates
- Reply and Quoted Messages
- GIFs
- Group Messages
GPTs are about to be everything everywhere, all at once.
This means businesses will build private/public GPTs for specific functions, from drafting and scrutinizing legal compliance documents to creating tailored sales agreements for clientele.
Trending Discussions on Chat
How can I match if the current route matches a pattern in React Router Dom v6?
Redis NodeJs server error,client is closed
Google Play app rejected due to: Prominent disclosure Non compliant design for policy: Accessibility API
JetpackCompose Navigation Nested Graphs cause "ViewModelStore should be set before setGraph call" exception
slack chat.postMessage API endpoint is not allowing the authorization header
React/Socket.io not displaying latest message passed down as prop
Avoid rerendering every component in list while updating only one in React
Google Play App Rejection - Not a core feature - Use of All files access
How to add count values in venn diagram for more than 6 sets?
What do the values for gitlab's predefiner variable CI_PIPELINE_SOURCE mean?
QUESTION
How can I match if the current route matches a pattern in React Router Dom v6?
Asked 2022-Apr-07 at 19:55I've got:
1export const ACCOUNT_PORTAL_PATHS = [
2 'home/*',
3 'my-care/*',
4 'chats/*',
5 'profile/*',
6 'programs/*',
7 'completion/*',
8 ]
9
If the current path is any of those, I want to know. I managed to get the current path with:
1export const ACCOUNT_PORTAL_PATHS = [
2 'home/*',
3 'my-care/*',
4 'chats/*',
5 'profile/*',
6 'programs/*',
7 'completion/*',
8 ]
9const { search: searchParams, pathname } = useLocation();
10
and that yields, in this example:
1export const ACCOUNT_PORTAL_PATHS = [
2 'home/*',
3 'my-care/*',
4 'chats/*',
5 'profile/*',
6 'programs/*',
7 'completion/*',
8 ]
9const { search: searchParams, pathname } = useLocation();
10pathname: "/my-care/1234"
11
What's the best way to match?
Thanks in advance!
ANSWER
Answered 2022-Apr-07 at 19:55If you just want to know if you are on a matching path, you can use the matchPath
function and test that some account path prefix is a match to the current pathname
.
Example:
1export const ACCOUNT_PORTAL_PATHS = [
2 'home/*',
3 'my-care/*',
4 'chats/*',
5 'profile/*',
6 'programs/*',
7 'completion/*',
8 ]
9const { search: searchParams, pathname } = useLocation();
10pathname: "/my-care/1234"
11import { matchPath } from "react-router-dom";
12
13...
14
15const { pathname } = useLocation();
16const isMatch = ACCOUNT_PORTAL_PATHS.some((path) =>
17 matchPath(path, pathname)
18);
19
QUESTION
Redis NodeJs server error,client is closed
Asked 2022-Feb-11 at 05:16I am developing an application where chats has to cached and monitored, currently it is an local application where i have installed redis and redis-cli.
The problem i'm facing is (node:5368) UnhandledPromiseRejectionWarning: Error: The client is closed
Attaching code snippet below
1//redis setup
2const redis = require('redis');
3const client = redis.createClient()//kept blank so that default options are available
4
5
6//runs when client connects
7io.on("connect", function (socket) {
8
9 //this is client side socket
10 //console.log("a new user connected...");
11
12 socket.on("join", function ({ name, room }, callback) {
13 //console.log(name, room);
14 const { msg, user } = addUser({ id: socket.id, name, room });
15 // console.log(user);
16 if (msg) return callback(msg); //accessible in frontend
17
18 //emit to all users
19 socket.emit("message", {
20 user: "Admin",
21 text: `Welcome to the room ${user.name}`,
22 });
23 //emit to all users except current one
24
25 socket.broadcast
26 .to(user.room)
27 .emit("message", { user: "Admin", text: `${user.name} has joined` });
28
29 socket.join(user.room); //pass the room that user wants to join
30
31 //get all users in the room
32 io.to(user.room).emit("roomData", {
33 room: user.room,
34 users: getUsersInRoom(user.room),
35 });
36
37 callback();
38 }); //end of join
39
40 //user generated messages
41 socket.on("sendMessage", async(message, callback)=>{
42 const user = getUser(socket.id);
43
44 //this is where we can store the messages in redis
45 await client.set("messages",message);
46
47 io.to(user.room).emit("message", { user: user.name, text: message });
48 console.log(client.get('messages'));
49 callback();
50 }); //end of sendMessage
51
52 //when user disconnects
53 socket.on("disconnect", function () {
54 const user = removeUser(socket.id);
55 if (user) {
56
57 console.log(client)
58
59 io.to(user.room).emit("message", {
60 user: "Admin",
61 text: `${user.name} has left `,
62 });
63 }
64 }); //end of disconnect
65
66
I am getting above error when user sends a message to the room or when socket.on("sendMessage")
is called.
Where am I going wrong?
Thank you in advance.
ANSWER
Answered 2021-Dec-01 at 20:16You should await client.connect()
before using the client
QUESTION
Google Play app rejected due to: Prominent disclosure Non compliant design for policy: Accessibility API
Asked 2022-Jan-28 at 06:22Our application is getting rejected from the play store for policy violation regarding
Prominent disclosure Non compliant design
for policy: Accessibility API
Initially we were using 3rd party library cobrowse, and they were using
android.permission.BIND_ACCESSIBILITY_SERVICE
and our app got rejected, after that, we had removed the library itself and now no accessibility permission is being asked in our manifest, and to comply with prominent disclosure we had taken the following steps:
- Added a Terms and conditions screen for all users.
- Added UI for prominent disclosure when requesting all permissions.
Note: Even tho we are not using the accessibility API, we kept its content as our rejection reason was still accessibility API even after removing service and library.
Target SDK: 31
We tried updating content and adding prominent disclosure UI still, the app is not getting accepted.
It's been 5 weeks and still no update from google over playstore, and they do not reply to emails, chats.
ANSWER
Answered 2021-Dec-22 at 11:00Okay after having a discussion with 3rd party lib, they updated lib to ask for accessibility permission and we added proper consent and permission disclosure screens in the app, and it worked !!
QUESTION
JetpackCompose Navigation Nested Graphs cause "ViewModelStore should be set before setGraph call" exception
Asked 2022-Jan-21 at 07:35I am trying to apply Jetpack Compose navigation into my application.
My Screens: Login/Register screens and Bottom navbar screens(call, chat, settings).
I already found out that the best way to do this is using nested graphs.
But I keep getting ViewModelStore should be set before setGraph call
exception. However, I don't think this is the right exception.
My navigation is already in the latest version. Probably my nested graph logic is not right.
Requirement: I want to be able to navigate from the Login or Register screen to any BottomBar Screen & reverse
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15
NavGraph.kt
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15fun NavGraphBuilder.loginNavGraph(
16 navController: NavHostController,
17 userViewModel: UserViewModel
18) {
19 navigation(
20 startDestination = Screen.LoginScreen.route,
21 route = LOGIN_GRAPH_ROUTE
22 ) {
23 composable(
24 route = Screen.LoginScreen.route,
25 content = {
26 LoginScreen(
27 navController = navController,
28 loginViewModel = userViewModel
29 )
30 })
31 composable(
32 route = Screen.RegisterScreen.route,
33 content = {
34 RegisterScreen(
35 navController = navController,
36 loginViewModel = userViewModel
37 )
38 })
39 }
40}
41
LoginNavGraph.kt
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15fun NavGraphBuilder.loginNavGraph(
16 navController: NavHostController,
17 userViewModel: UserViewModel
18) {
19 navigation(
20 startDestination = Screen.LoginScreen.route,
21 route = LOGIN_GRAPH_ROUTE
22 ) {
23 composable(
24 route = Screen.LoginScreen.route,
25 content = {
26 LoginScreen(
27 navController = navController,
28 loginViewModel = userViewModel
29 )
30 })
31 composable(
32 route = Screen.RegisterScreen.route,
33 content = {
34 RegisterScreen(
35 navController = navController,
36 loginViewModel = userViewModel
37 )
38 })
39 }
40}
41fun NavGraphBuilder.bottomBarNavGraph(
42 navController: NavHostController,
43 userViewModel: UserViewModel
44) {
45 navigation(
46 startDestination = Screen.AppScaffold.route,
47 route = BOTTOM_BAR_GRAPH_ROUTE
48 ) {
49 composable(
50 route = Screen.AppScaffold.route,
51 content = {
52 AppScaffold(
53 navController = navController,
54 userViewModel = userViewModel
55 )
56 })
57 }
58}
59
BottomBarNavGraph.kt
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15fun NavGraphBuilder.loginNavGraph(
16 navController: NavHostController,
17 userViewModel: UserViewModel
18) {
19 navigation(
20 startDestination = Screen.LoginScreen.route,
21 route = LOGIN_GRAPH_ROUTE
22 ) {
23 composable(
24 route = Screen.LoginScreen.route,
25 content = {
26 LoginScreen(
27 navController = navController,
28 loginViewModel = userViewModel
29 )
30 })
31 composable(
32 route = Screen.RegisterScreen.route,
33 content = {
34 RegisterScreen(
35 navController = navController,
36 loginViewModel = userViewModel
37 )
38 })
39 }
40}
41fun NavGraphBuilder.bottomBarNavGraph(
42 navController: NavHostController,
43 userViewModel: UserViewModel
44) {
45 navigation(
46 startDestination = Screen.AppScaffold.route,
47 route = BOTTOM_BAR_GRAPH_ROUTE
48 ) {
49 composable(
50 route = Screen.AppScaffold.route,
51 content = {
52 AppScaffold(
53 navController = navController,
54 userViewModel = userViewModel
55 )
56 })
57 }
58}
59@Composable
60fun AppScaffold(
61 navController: NavHostController,
62 userViewModel: UserViewModel
63) {
64 val scaffoldState = rememberScaffoldState()
65
66 Scaffold(
67
68 bottomBar = {
69 BottomBar(mainNavController = navController)
70 },
71 scaffoldState = scaffoldState,
72
73 ) {
74
75 NavHost(
76 navController = navController,
77 startDestination = NavigationScreen.EmergencyCallScreen.route
78 ) {
79 composable(NavigationScreen.EmergencyCallScreen.route) {
80 EmergencyCallScreen(
81 navController = navController,
82 loginViewModel = userViewModel
83 )
84 }
85 composable(NavigationScreen.ChatScreen.route) { ChatScreen() }
86 composable(NavigationScreen.SettingsScreen.route) {
87 SettingsScreen(
88 navController = navController,
89 loginViewModel = userViewModel
90 )
91 }
92 }
93 }
94}
95
AppScaffold.kt
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15fun NavGraphBuilder.loginNavGraph(
16 navController: NavHostController,
17 userViewModel: UserViewModel
18) {
19 navigation(
20 startDestination = Screen.LoginScreen.route,
21 route = LOGIN_GRAPH_ROUTE
22 ) {
23 composable(
24 route = Screen.LoginScreen.route,
25 content = {
26 LoginScreen(
27 navController = navController,
28 loginViewModel = userViewModel
29 )
30 })
31 composable(
32 route = Screen.RegisterScreen.route,
33 content = {
34 RegisterScreen(
35 navController = navController,
36 loginViewModel = userViewModel
37 )
38 })
39 }
40}
41fun NavGraphBuilder.bottomBarNavGraph(
42 navController: NavHostController,
43 userViewModel: UserViewModel
44) {
45 navigation(
46 startDestination = Screen.AppScaffold.route,
47 route = BOTTOM_BAR_GRAPH_ROUTE
48 ) {
49 composable(
50 route = Screen.AppScaffold.route,
51 content = {
52 AppScaffold(
53 navController = navController,
54 userViewModel = userViewModel
55 )
56 })
57 }
58}
59@Composable
60fun AppScaffold(
61 navController: NavHostController,
62 userViewModel: UserViewModel
63) {
64 val scaffoldState = rememberScaffoldState()
65
66 Scaffold(
67
68 bottomBar = {
69 BottomBar(mainNavController = navController)
70 },
71 scaffoldState = scaffoldState,
72
73 ) {
74
75 NavHost(
76 navController = navController,
77 startDestination = NavigationScreen.EmergencyCallScreen.route
78 ) {
79 composable(NavigationScreen.EmergencyCallScreen.route) {
80 EmergencyCallScreen(
81 navController = navController,
82 loginViewModel = userViewModel
83 )
84 }
85 composable(NavigationScreen.ChatScreen.route) { ChatScreen() }
86 composable(NavigationScreen.SettingsScreen.route) {
87 SettingsScreen(
88 navController = navController,
89 loginViewModel = userViewModel
90 )
91 }
92 }
93 }
94}
95@Composable
96fun BottomBar(mainNavController: NavHostController) {
97
98 val items = listOf(
99 NavigationScreen.EmergencyCallScreen,
100 NavigationScreen.ChatScreen,
101 NavigationScreen.SettingsScreen,
102 )
103
104 BottomNavigation(
105 elevation = 5.dp,
106 ) {
107 val navBackStackEntry by mainNavController.currentBackStackEntryAsState()
108 val currentRoute = navBackStackEntry?.destination?.route
109 items.map {
110 BottomNavigationItem(
111 icon = {
112 Icon(
113 painter = painterResource(id = it.icon),
114 contentDescription = it.title
115 )
116 },
117 label = {
118 Text(
119 text = it.title
120 )
121 },
122 selected = currentRoute == it.route,
123 selectedContentColor = Color.White,
124 unselectedContentColor = Color.White.copy(alpha = 0.4f),
125 onClick = {
126 mainNavController.navigate(it.route) {
127 mainNavController.graph.startDestinationRoute?.let { route ->
128 popUpTo(route) {
129 saveState = true
130 }
131 }
132 restoreState = true
133 launchSingleTop = true
134 }
135 },
136
137 )
138 }
139
140 }
141}
142
BottomBar.kt
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15fun NavGraphBuilder.loginNavGraph(
16 navController: NavHostController,
17 userViewModel: UserViewModel
18) {
19 navigation(
20 startDestination = Screen.LoginScreen.route,
21 route = LOGIN_GRAPH_ROUTE
22 ) {
23 composable(
24 route = Screen.LoginScreen.route,
25 content = {
26 LoginScreen(
27 navController = navController,
28 loginViewModel = userViewModel
29 )
30 })
31 composable(
32 route = Screen.RegisterScreen.route,
33 content = {
34 RegisterScreen(
35 navController = navController,
36 loginViewModel = userViewModel
37 )
38 })
39 }
40}
41fun NavGraphBuilder.bottomBarNavGraph(
42 navController: NavHostController,
43 userViewModel: UserViewModel
44) {
45 navigation(
46 startDestination = Screen.AppScaffold.route,
47 route = BOTTOM_BAR_GRAPH_ROUTE
48 ) {
49 composable(
50 route = Screen.AppScaffold.route,
51 content = {
52 AppScaffold(
53 navController = navController,
54 userViewModel = userViewModel
55 )
56 })
57 }
58}
59@Composable
60fun AppScaffold(
61 navController: NavHostController,
62 userViewModel: UserViewModel
63) {
64 val scaffoldState = rememberScaffoldState()
65
66 Scaffold(
67
68 bottomBar = {
69 BottomBar(mainNavController = navController)
70 },
71 scaffoldState = scaffoldState,
72
73 ) {
74
75 NavHost(
76 navController = navController,
77 startDestination = NavigationScreen.EmergencyCallScreen.route
78 ) {
79 composable(NavigationScreen.EmergencyCallScreen.route) {
80 EmergencyCallScreen(
81 navController = navController,
82 loginViewModel = userViewModel
83 )
84 }
85 composable(NavigationScreen.ChatScreen.route) { ChatScreen() }
86 composable(NavigationScreen.SettingsScreen.route) {
87 SettingsScreen(
88 navController = navController,
89 loginViewModel = userViewModel
90 )
91 }
92 }
93 }
94}
95@Composable
96fun BottomBar(mainNavController: NavHostController) {
97
98 val items = listOf(
99 NavigationScreen.EmergencyCallScreen,
100 NavigationScreen.ChatScreen,
101 NavigationScreen.SettingsScreen,
102 )
103
104 BottomNavigation(
105 elevation = 5.dp,
106 ) {
107 val navBackStackEntry by mainNavController.currentBackStackEntryAsState()
108 val currentRoute = navBackStackEntry?.destination?.route
109 items.map {
110 BottomNavigationItem(
111 icon = {
112 Icon(
113 painter = painterResource(id = it.icon),
114 contentDescription = it.title
115 )
116 },
117 label = {
118 Text(
119 text = it.title
120 )
121 },
122 selected = currentRoute == it.route,
123 selectedContentColor = Color.White,
124 unselectedContentColor = Color.White.copy(alpha = 0.4f),
125 onClick = {
126 mainNavController.navigate(it.route) {
127 mainNavController.graph.startDestinationRoute?.let { route ->
128 popUpTo(route) {
129 saveState = true
130 }
131 }
132 restoreState = true
133 launchSingleTop = true
134 }
135 },
136
137 )
138 }
139
140 }
141}
142const val ROOT_GRAPH_ROUTE = "root"
143const val LOGIN_GRAPH_ROUTE = "login_register"
144const val BOTTOM_BAR_GRAPH_ROUTE = "bottom_bar"
145
146sealed class Screen(val route: String) {
147 object LoginScreen : Screen("login_screen")
148 object RegisterScreen : Screen("register_screen")
149 object AppScaffold : Screen("app_scaffold")
150
151}
152
Screen.kt
1@Composable
2fun SetupNavGraph(
3 navController: NavHostController,
4 userViewModel: UserViewModel
5) {
6 NavHost(
7 navController = navController,
8 startDestination = BOTTOM_BAR_GRAPH_ROUTE,
9 route = ROOT_GRAPH_ROUTE
10 ) {
11 loginNavGraph(navController = navController, userViewModel)
12 bottomBarNavGraph(navController = navController, userViewModel)
13 }
14}
15fun NavGraphBuilder.loginNavGraph(
16 navController: NavHostController,
17 userViewModel: UserViewModel
18) {
19 navigation(
20 startDestination = Screen.LoginScreen.route,
21 route = LOGIN_GRAPH_ROUTE
22 ) {
23 composable(
24 route = Screen.LoginScreen.route,
25 content = {
26 LoginScreen(
27 navController = navController,
28 loginViewModel = userViewModel
29 )
30 })
31 composable(
32 route = Screen.RegisterScreen.route,
33 content = {
34 RegisterScreen(
35 navController = navController,
36 loginViewModel = userViewModel
37 )
38 })
39 }
40}
41fun NavGraphBuilder.bottomBarNavGraph(
42 navController: NavHostController,
43 userViewModel: UserViewModel
44) {
45 navigation(
46 startDestination = Screen.AppScaffold.route,
47 route = BOTTOM_BAR_GRAPH_ROUTE
48 ) {
49 composable(
50 route = Screen.AppScaffold.route,
51 content = {
52 AppScaffold(
53 navController = navController,
54 userViewModel = userViewModel
55 )
56 })
57 }
58}
59@Composable
60fun AppScaffold(
61 navController: NavHostController,
62 userViewModel: UserViewModel
63) {
64 val scaffoldState = rememberScaffoldState()
65
66 Scaffold(
67
68 bottomBar = {
69 BottomBar(mainNavController = navController)
70 },
71 scaffoldState = scaffoldState,
72
73 ) {
74
75 NavHost(
76 navController = navController,
77 startDestination = NavigationScreen.EmergencyCallScreen.route
78 ) {
79 composable(NavigationScreen.EmergencyCallScreen.route) {
80 EmergencyCallScreen(
81 navController = navController,
82 loginViewModel = userViewModel
83 )
84 }
85 composable(NavigationScreen.ChatScreen.route) { ChatScreen() }
86 composable(NavigationScreen.SettingsScreen.route) {
87 SettingsScreen(
88 navController = navController,
89 loginViewModel = userViewModel
90 )
91 }
92 }
93 }
94}
95@Composable
96fun BottomBar(mainNavController: NavHostController) {
97
98 val items = listOf(
99 NavigationScreen.EmergencyCallScreen,
100 NavigationScreen.ChatScreen,
101 NavigationScreen.SettingsScreen,
102 )
103
104 BottomNavigation(
105 elevation = 5.dp,
106 ) {
107 val navBackStackEntry by mainNavController.currentBackStackEntryAsState()
108 val currentRoute = navBackStackEntry?.destination?.route
109 items.map {
110 BottomNavigationItem(
111 icon = {
112 Icon(
113 painter = painterResource(id = it.icon),
114 contentDescription = it.title
115 )
116 },
117 label = {
118 Text(
119 text = it.title
120 )
121 },
122 selected = currentRoute == it.route,
123 selectedContentColor = Color.White,
124 unselectedContentColor = Color.White.copy(alpha = 0.4f),
125 onClick = {
126 mainNavController.navigate(it.route) {
127 mainNavController.graph.startDestinationRoute?.let { route ->
128 popUpTo(route) {
129 saveState = true
130 }
131 }
132 restoreState = true
133 launchSingleTop = true
134 }
135 },
136
137 )
138 }
139
140 }
141}
142const val ROOT_GRAPH_ROUTE = "root"
143const val LOGIN_GRAPH_ROUTE = "login_register"
144const val BOTTOM_BAR_GRAPH_ROUTE = "bottom_bar"
145
146sealed class Screen(val route: String) {
147 object LoginScreen : Screen("login_screen")
148 object RegisterScreen : Screen("register_screen")
149 object AppScaffold : Screen("app_scaffold")
150
151}
152sealed class NavigationScreen(val route: String, val title: String, @DrawableRes val icon: Int) {
153 object EmergencyCallScreen : NavigationScreen(
154 route = "emergency_call_screen",
155 title = "Emergency Call",
156 icon = R.drawable.ic_phone
157 )
158
159 object ChatScreen :
160 NavigationScreen(
161 route = "chat_screen",
162 title = "Chat",
163 icon = R.drawable.ic_chat)
164
165 object SettingsScreen : NavigationScreen(
166 route = "settings_screen",
167 title = "Settings",
168 icon = R.drawable.ic_settings
169 )
170}
171
NavigationScreen.kt
ANSWER
Answered 2021-Nov-13 at 16:37Nesting of NavHost is not allowed. It results in ViewModelStore should be set before setGraph call Exception. Generally, the bottom nav is outside of the NavHost, which is what the docs show. The recommended approach is a single NavHost, where you hide and show your bottom nav based on what destination you are on.
QUESTION
slack chat.postMessage API endpoint is not allowing the authorization header
Asked 2022-Jan-17 at 23:28I have this code running in the browser
1<html>
2
3 <script type="module">
4 console.log("working");
5
6 var url = "https://slack.com/api/chat.postMessage";
7 var auth_token = "xoxb-2B"; //Your Bot's auth token
8 var body = {channel: "ses", text: "testing app"}
9
10 async function postData(url = '', data = {}) {
11 // Default options are marked with *
12 const response = await fetch(url, {
13 method: 'POST', // *GET, POST, PUT, DELETE, etc.
14 headers: {
15 "Authorization": "Bearer " + auth_token,
16 "Content-Type" : "application/json"
17 },
18 body: JSON.stringify(data) // body data type must match "Content-Type" header
19 });
20 return response.json(); // parses JSON response into native JavaScript objects
21 }
22
23 postData('https://slack.com/api/chat.postMessage', body)
24 .then(data => {
25 console.log(data); // JSON data parsed by `data.json()` call
26 });
27 </script>
28</html>
29
I'm getting
Access to fetch at 'https://slack.com/api/chat.postMessage' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
I don't understand, I need to specify the bearer token somehow, even in the docs it says to put it in the Authorization header, why aren't they allowing it?
ANSWER
Answered 2022-Jan-17 at 23:28I don't understand, I need to specify the bearer token somehow, even in the docs it says to put it in the Authorization header, why aren't they allowing it?
This is a different problem, is not related to the Bearer token at all. From the error you're getting, it means, the origin you're using to fetch the Slack API, is not trusted (http://127.0.0.1:5500), there is nothing you can do from the browser since this is a policy that comes from the server which defines the authorized origins. (Learn more about CORS here) Since I don't think this is supported by Slack, you will need to fetch the Slack API from the server.
One way to solve this, is by exposing a backend API, for example:
Post a message to Slack | Run in Fusebit |
---|
1<html>
2
3 <script type="module">
4 console.log("working");
5
6 var url = "https://slack.com/api/chat.postMessage";
7 var auth_token = "xoxb-2B"; //Your Bot's auth token
8 var body = {channel: "ses", text: "testing app"}
9
10 async function postData(url = '', data = {}) {
11 // Default options are marked with *
12 const response = await fetch(url, {
13 method: 'POST', // *GET, POST, PUT, DELETE, etc.
14 headers: {
15 "Authorization": "Bearer " + auth_token,
16 "Content-Type" : "application/json"
17 },
18 body: JSON.stringify(data) // body data type must match "Content-Type" header
19 });
20 return response.json(); // parses JSON response into native JavaScript objects
21 }
22
23 postData('https://slack.com/api/chat.postMessage', body)
24 .then(data => {
25 console.log(data); // JSON data parsed by `data.json()` call
26 });
27 </script>
28</html>
29router.post('/api/tenant/:tenantId/test', async (ctx) => {
30 // Create a Slack client pre-configured with credentials necessary to communicate with your tenant's Slack workspace.
31 // For the Slack SDK documentation, see https://slack.dev/node-slack-sdk/web-api.
32 const slackClient = await integration.tenant.getSdkByTenant(ctx, connectorName, ctx.params.tenantId);
33
34 // Get the Slack user ID associated with your tenant
35 const slackUserId = slackClient.fusebit.credentials.authed_user.id;
36
37 // Send a Direct Message to the Slack user
38 const result = await slackClient.chat.postMessage({
39 text: 'Hello world!',
40 channel: slackUserId,
41 });
42
43 console.log('message response', result.message);
44 ctx.body = { message: `Successfully sent a message to Slack user ${slackUserId}!` };
45});
46
47
QUESTION
React/Socket.io not displaying latest message passed down as prop
Asked 2022-Jan-13 at 17:37I am working on a chat application using React and socket.io. Back end is express/node. The relevant components are: Room.js --> Chat.js --> Messages.js --> Message.js
messageData received from the server is stored in state in Room.js. It is then passed down through Chat.js to Messages.js, where it is mapped onto a series of Message.js components.
When messages are received, they ARE appearing, but only after I start typing in the form again, triggering messageChangeHandler(). Any ideas why the Messages won't re-render when a new message is received and added to state in Room.js? I have confirmed that the state and props are updating everywhere they should be--they just aren't appearing/re-rendering until messageChangeHandler() triggers its own re-render.
Here are the components.
Room.js
1export default function Room(props) {
2 const [messagesData, setMessagesData] = useState([])
3
4 useEffect(() => {
5 console.log('the use effect ')
6 socket.on('broadcast', data => {
7 console.log(messagesData)
8 let previousData = messagesData
9 previousData.push(data)
10 // buildMessages(previousData)
11 setMessagesData(previousData)
12 })
13 }, [socket])
14
15
16 console.log('this is messagesData in queue.js', messagesData)
17
18 return(
19 // queue counter will go up here
20 // <QueueDisplay />
21
22 // chat goes here
23 <Chat
24 profile={props.profile}
25 messagesData={messagesData}
26 />
27
28 )
29}
30
Chat.js
1export default function Room(props) {
2 const [messagesData, setMessagesData] = useState([])
3
4 useEffect(() => {
5 console.log('the use effect ')
6 socket.on('broadcast', data => {
7 console.log(messagesData)
8 let previousData = messagesData
9 previousData.push(data)
10 // buildMessages(previousData)
11 setMessagesData(previousData)
12 })
13 }, [socket])
14
15
16 console.log('this is messagesData in queue.js', messagesData)
17
18 return(
19 // queue counter will go up here
20 // <QueueDisplay />
21
22 // chat goes here
23 <Chat
24 profile={props.profile}
25 messagesData={messagesData}
26 />
27
28 )
29}
30export default function Chat(props) {
31 // state
32 const [newPayload, setNewPayload] = useState({
33 message: '',
34 sender: props.profile.name
35 })
36 // const [messagesData, setMessagesData] = useState([])
37 const [updateToggle, setUpdateToggle] = useState(true)
38
39
40 const messageChangeHandler = (e) => {
41 setNewPayload({... newPayload, [e.target.name]: e.target.value})
42 }
43
44 const messageSend = (e) => {
45 e.preventDefault()
46 if (newPayload.message) {
47 socket.emit('chat message', newPayload)
48 setNewPayload({
49 message: '',
50 sender: props.profile.name
51 })
52 }
53 }
54
55 return(
56 <div id='chatbox'>
57 <div id='messages'>
58 <Messages messagesData={props.messagesData} />
59 </div>
60 <form onSubmit={messageSend}>
61 <input
62 type="text"
63 name="message"
64 id="message"
65 placeholder="Start a new message"
66 onChange={messageChangeHandler}
67 value={newPayload.message}
68 autoComplete='off'
69 />
70 <input type="submit" value="Send" />
71 </form>
72 </div>
73 )
74}
75
Messages.js
1export default function Room(props) {
2 const [messagesData, setMessagesData] = useState([])
3
4 useEffect(() => {
5 console.log('the use effect ')
6 socket.on('broadcast', data => {
7 console.log(messagesData)
8 let previousData = messagesData
9 previousData.push(data)
10 // buildMessages(previousData)
11 setMessagesData(previousData)
12 })
13 }, [socket])
14
15
16 console.log('this is messagesData in queue.js', messagesData)
17
18 return(
19 // queue counter will go up here
20 // <QueueDisplay />
21
22 // chat goes here
23 <Chat
24 profile={props.profile}
25 messagesData={messagesData}
26 />
27
28 )
29}
30export default function Chat(props) {
31 // state
32 const [newPayload, setNewPayload] = useState({
33 message: '',
34 sender: props.profile.name
35 })
36 // const [messagesData, setMessagesData] = useState([])
37 const [updateToggle, setUpdateToggle] = useState(true)
38
39
40 const messageChangeHandler = (e) => {
41 setNewPayload({... newPayload, [e.target.name]: e.target.value})
42 }
43
44 const messageSend = (e) => {
45 e.preventDefault()
46 if (newPayload.message) {
47 socket.emit('chat message', newPayload)
48 setNewPayload({
49 message: '',
50 sender: props.profile.name
51 })
52 }
53 }
54
55 return(
56 <div id='chatbox'>
57 <div id='messages'>
58 <Messages messagesData={props.messagesData} />
59 </div>
60 <form onSubmit={messageSend}>
61 <input
62 type="text"
63 name="message"
64 id="message"
65 placeholder="Start a new message"
66 onChange={messageChangeHandler}
67 value={newPayload.message}
68 autoComplete='off'
69 />
70 <input type="submit" value="Send" />
71 </form>
72 </div>
73 )
74}
75export default function Messages(props) {
76 return(
77 <>
78 {props.messagesData.map((data, i) => {
79 return <Message key={i} sender={data.sender} message={data.message} />
80 })}
81 </>
82 )
83}
84
Message.js
1export default function Room(props) {
2 const [messagesData, setMessagesData] = useState([])
3
4 useEffect(() => {
5 console.log('the use effect ')
6 socket.on('broadcast', data => {
7 console.log(messagesData)
8 let previousData = messagesData
9 previousData.push(data)
10 // buildMessages(previousData)
11 setMessagesData(previousData)
12 })
13 }, [socket])
14
15
16 console.log('this is messagesData in queue.js', messagesData)
17
18 return(
19 // queue counter will go up here
20 // <QueueDisplay />
21
22 // chat goes here
23 <Chat
24 profile={props.profile}
25 messagesData={messagesData}
26 />
27
28 )
29}
30export default function Chat(props) {
31 // state
32 const [newPayload, setNewPayload] = useState({
33 message: '',
34 sender: props.profile.name
35 })
36 // const [messagesData, setMessagesData] = useState([])
37 const [updateToggle, setUpdateToggle] = useState(true)
38
39
40 const messageChangeHandler = (e) => {
41 setNewPayload({... newPayload, [e.target.name]: e.target.value})
42 }
43
44 const messageSend = (e) => {
45 e.preventDefault()
46 if (newPayload.message) {
47 socket.emit('chat message', newPayload)
48 setNewPayload({
49 message: '',
50 sender: props.profile.name
51 })
52 }
53 }
54
55 return(
56 <div id='chatbox'>
57 <div id='messages'>
58 <Messages messagesData={props.messagesData} />
59 </div>
60 <form onSubmit={messageSend}>
61 <input
62 type="text"
63 name="message"
64 id="message"
65 placeholder="Start a new message"
66 onChange={messageChangeHandler}
67 value={newPayload.message}
68 autoComplete='off'
69 />
70 <input type="submit" value="Send" />
71 </form>
72 </div>
73 )
74}
75export default function Messages(props) {
76 return(
77 <>
78 {props.messagesData.map((data, i) => {
79 return <Message key={i} sender={data.sender} message={data.message} />
80 })}
81 </>
82 )
83}
84export default function Message(props) {
85 return(
86 <div key={props.key}>
87 <p>{props.sender}</p>
88 <p>{props.message}</p>
89 </div>
90 )
91}
92
Thank you in advance for any help!
ANSWER
Answered 2022-Jan-11 at 19:44Changing the useEffect in room to contain the following fixed the issue:
1export default function Room(props) {
2 const [messagesData, setMessagesData] = useState([])
3
4 useEffect(() => {
5 console.log('the use effect ')
6 socket.on('broadcast', data => {
7 console.log(messagesData)
8 let previousData = messagesData
9 previousData.push(data)
10 // buildMessages(previousData)
11 setMessagesData(previousData)
12 })
13 }, [socket])
14
15
16 console.log('this is messagesData in queue.js', messagesData)
17
18 return(
19 // queue counter will go up here
20 // <QueueDisplay />
21
22 // chat goes here
23 <Chat
24 profile={props.profile}
25 messagesData={messagesData}
26 />
27
28 )
29}
30export default function Chat(props) {
31 // state
32 const [newPayload, setNewPayload] = useState({
33 message: '',
34 sender: props.profile.name
35 })
36 // const [messagesData, setMessagesData] = useState([])
37 const [updateToggle, setUpdateToggle] = useState(true)
38
39
40 const messageChangeHandler = (e) => {
41 setNewPayload({... newPayload, [e.target.name]: e.target.value})
42 }
43
44 const messageSend = (e) => {
45 e.preventDefault()
46 if (newPayload.message) {
47 socket.emit('chat message', newPayload)
48 setNewPayload({
49 message: '',
50 sender: props.profile.name
51 })
52 }
53 }
54
55 return(
56 <div id='chatbox'>
57 <div id='messages'>
58 <Messages messagesData={props.messagesData} />
59 </div>
60 <form onSubmit={messageSend}>
61 <input
62 type="text"
63 name="message"
64 id="message"
65 placeholder="Start a new message"
66 onChange={messageChangeHandler}
67 value={newPayload.message}
68 autoComplete='off'
69 />
70 <input type="submit" value="Send" />
71 </form>
72 </div>
73 )
74}
75export default function Messages(props) {
76 return(
77 <>
78 {props.messagesData.map((data, i) => {
79 return <Message key={i} sender={data.sender} message={data.message} />
80 })}
81 </>
82 )
83}
84export default function Message(props) {
85 return(
86 <div key={props.key}>
87 <p>{props.sender}</p>
88 <p>{props.message}</p>
89 </div>
90 )
91}
92 useEffect(() => {
93 console.log('the use effect ')
94 socket.on('broadcast', data => {
95 console.log(messagesData)
96 // let previousData = messagesData
97 // previousData.push(data)
98 // setMessagesData(previousData)
99 setMessagesData(prev => prev.concat([data]))
100 })
101 }, [socket])```
102
QUESTION
Avoid rerendering every component in list while updating only one in React
Asked 2021-Dec-17 at 07:39I have a simple chat app using Firebase v9, with these components from parent to child in this hierarchical order: ChatSection
, Chat
, ChatLine
, EditMessage
.
I have a custom hook named useChatService
holding the list of messages
in state, the hook is called in ChatSection
, the hook returns the messages
and I pass them from ChatSection
in a prop to Chat
, then I loop through messages
and create a ChatLine
component for every message.
I can click the Edit
button in front of each message, it shows the EditMessage
component so I can edit the text, then when I press "Enter", the function updateMessage
gets executed and updates the message in the db, but then every single ChatLine
gets rerendered again, which is a problem as the list gets bigger.
EDIT 2: I've completed the code to make a working example with Firebase v9 so you can visualize the rerenders I'm talking about after every (add, edit or delete) of a message. I'm using ReactDevTools Profiler to track rerenders.
- Here is the full updated code: CodeSandbox
- Also deployed on: Netlify
ChatSection.js
:
1import useChatService from "../hooks/useChatService";
2import { useEffect } from "react";
3import Chat from "./Chat";
4import NoChat from "./NoChat";
5import ChatInput from "./ChatInput";
6
7const ChatSection = () => {
8 let unsubscribe;
9 const { getChatAndUnsub, messages } = useChatService();
10
11 useEffect(() => {
12 const getChat = async () => {
13 unsubscribe = await getChatAndUnsub();
14 };
15
16 getChat();
17
18 return () => {
19 unsubscribe?.();
20 };
21 }, []);
22
23 return (
24 <div>
25 {messages.length ? <Chat messages={messages} /> : <NoChat />}
26 <p>ADD A MESSAGE</p>
27 <ChatInput />
28 </div>
29 );
30};
31
32export default ChatSection;
33
Chat.js
:
1import useChatService from "../hooks/useChatService";
2import { useEffect } from "react";
3import Chat from "./Chat";
4import NoChat from "./NoChat";
5import ChatInput from "./ChatInput";
6
7const ChatSection = () => {
8 let unsubscribe;
9 const { getChatAndUnsub, messages } = useChatService();
10
11 useEffect(() => {
12 const getChat = async () => {
13 unsubscribe = await getChatAndUnsub();
14 };
15
16 getChat();
17
18 return () => {
19 unsubscribe?.();
20 };
21 }, []);
22
23 return (
24 <div>
25 {messages.length ? <Chat messages={messages} /> : <NoChat />}
26 <p>ADD A MESSAGE</p>
27 <ChatInput />
28 </div>
29 );
30};
31
32export default ChatSection;
33import { useState } from "react";
34import ChatLine from "./ChatLine";
35import useChatService from "../hooks/useChatService";
36
37const Chat = ({ messages }) => {
38 const [editValue, setEditValue] = useState("");
39 const [editingId, setEditingId] = useState(null);
40
41 const { updateMessage, deleteMessage } = useChatService();
42
43 return (
44 <div>
45 <p>MESSAGES :</p>
46 {messages.map((line) => (
47 <ChatLine
48 key={line.id}
49 line={line}
50 editValue={line.id === editingId ? editValue : ""}
51 setEditValue={setEditValue}
52 editingId={line.id === editingId ? editingId : null}
53 setEditingId={setEditingId}
54 updateMessage={updateMessage}
55 deleteMessage={deleteMessage}
56 />
57 ))}
58 </div>
59 );
60};
61
62export default Chat;
63
ChatInput
:
1import useChatService from "../hooks/useChatService";
2import { useEffect } from "react";
3import Chat from "./Chat";
4import NoChat from "./NoChat";
5import ChatInput from "./ChatInput";
6
7const ChatSection = () => {
8 let unsubscribe;
9 const { getChatAndUnsub, messages } = useChatService();
10
11 useEffect(() => {
12 const getChat = async () => {
13 unsubscribe = await getChatAndUnsub();
14 };
15
16 getChat();
17
18 return () => {
19 unsubscribe?.();
20 };
21 }, []);
22
23 return (
24 <div>
25 {messages.length ? <Chat messages={messages} /> : <NoChat />}
26 <p>ADD A MESSAGE</p>
27 <ChatInput />
28 </div>
29 );
30};
31
32export default ChatSection;
33import { useState } from "react";
34import ChatLine from "./ChatLine";
35import useChatService from "../hooks/useChatService";
36
37const Chat = ({ messages }) => {
38 const [editValue, setEditValue] = useState("");
39 const [editingId, setEditingId] = useState(null);
40
41 const { updateMessage, deleteMessage } = useChatService();
42
43 return (
44 <div>
45 <p>MESSAGES :</p>
46 {messages.map((line) => (
47 <ChatLine
48 key={line.id}
49 line={line}
50 editValue={line.id === editingId ? editValue : ""}
51 setEditValue={setEditValue}
52 editingId={line.id === editingId ? editingId : null}
53 setEditingId={setEditingId}
54 updateMessage={updateMessage}
55 deleteMessage={deleteMessage}
56 />
57 ))}
58 </div>
59 );
60};
61
62export default Chat;
63import { useState } from "react";
64import useChatService from "../hooks/useChatService";
65
66const ChatInput = () => {
67 const [inputValue, setInputValue] = useState("");
68 const { addMessage } = useChatService();
69
70 return (
71 <textarea
72 onKeyPress={(e) => {
73 if (e.key === "Enter") {
74 e.preventDefault();
75 addMessage(inputValue);
76 setInputValue("");
77 }
78 }}
79 placeholder="new message..."
80 onChange={(e) => {
81 setInputValue(e.target.value);
82 }}
83 value={inputValue}
84 autoFocus
85 />
86 );
87};
88
89export default ChatInput;
90
ChatLine.js
:
1import useChatService from "../hooks/useChatService";
2import { useEffect } from "react";
3import Chat from "./Chat";
4import NoChat from "./NoChat";
5import ChatInput from "./ChatInput";
6
7const ChatSection = () => {
8 let unsubscribe;
9 const { getChatAndUnsub, messages } = useChatService();
10
11 useEffect(() => {
12 const getChat = async () => {
13 unsubscribe = await getChatAndUnsub();
14 };
15
16 getChat();
17
18 return () => {
19 unsubscribe?.();
20 };
21 }, []);
22
23 return (
24 <div>
25 {messages.length ? <Chat messages={messages} /> : <NoChat />}
26 <p>ADD A MESSAGE</p>
27 <ChatInput />
28 </div>
29 );
30};
31
32export default ChatSection;
33import { useState } from "react";
34import ChatLine from "./ChatLine";
35import useChatService from "../hooks/useChatService";
36
37const Chat = ({ messages }) => {
38 const [editValue, setEditValue] = useState("");
39 const [editingId, setEditingId] = useState(null);
40
41 const { updateMessage, deleteMessage } = useChatService();
42
43 return (
44 <div>
45 <p>MESSAGES :</p>
46 {messages.map((line) => (
47 <ChatLine
48 key={line.id}
49 line={line}
50 editValue={line.id === editingId ? editValue : ""}
51 setEditValue={setEditValue}
52 editingId={line.id === editingId ? editingId : null}
53 setEditingId={setEditingId}
54 updateMessage={updateMessage}
55 deleteMessage={deleteMessage}
56 />
57 ))}
58 </div>
59 );
60};
61
62export default Chat;
63import { useState } from "react";
64import useChatService from "../hooks/useChatService";
65
66const ChatInput = () => {
67 const [inputValue, setInputValue] = useState("");
68 const { addMessage } = useChatService();
69
70 return (
71 <textarea
72 onKeyPress={(e) => {
73 if (e.key === "Enter") {
74 e.preventDefault();
75 addMessage(inputValue);
76 setInputValue("");
77 }
78 }}
79 placeholder="new message..."
80 onChange={(e) => {
81 setInputValue(e.target.value);
82 }}
83 value={inputValue}
84 autoFocus
85 />
86 );
87};
88
89export default ChatInput;
90import EditMessage from "./EditMessage";
91import { memo } from "react";
92
93const ChatLine = ({
94 line,
95 editValue,
96 setEditValue,
97 editingId,
98 setEditingId,
99 updateMessage,
100 deleteMessage,
101}) => {
102 return (
103 <div>
104 {editingId !== line.id ? (
105 <>
106 <span style={{ marginRight: "20px" }}>{line.id}: </span>
107 <span style={{ marginRight: "20px" }}>[{line.displayName}]</span>
108 <span style={{ marginRight: "20px" }}>{line.message}</span>
109 <button
110 onClick={() => {
111 setEditingId(line.id);
112 setEditValue(line.message);
113 }}
114 >
115 EDIT
116 </button>
117 <button
118 onClick={() => {
119 deleteMessage(line.id);
120 }}
121 >
122 DELETE
123 </button>
124 </>
125 ) : (
126 <EditMessage
127 editValue={editValue}
128 setEditValue={setEditValue}
129 setEditingId={setEditingId}
130 editingId={editingId}
131 updateMessage={updateMessage}
132 />
133 )}
134 </div>
135 );
136};
137
138export default memo(ChatLine);
139
EditMessage.js
:
1import useChatService from "../hooks/useChatService";
2import { useEffect } from "react";
3import Chat from "./Chat";
4import NoChat from "./NoChat";
5import ChatInput from "./ChatInput";
6
7const ChatSection = () => {
8 let unsubscribe;
9 const { getChatAndUnsub, messages } = useChatService();
10
11 useEffect(() => {
12 const getChat = async () => {
13 unsubscribe = await getChatAndUnsub();
14 };
15
16 getChat();
17
18 return () => {
19 unsubscribe?.();
20 };
21 }, []);
22
23 return (
24 <div>
25 {messages.length ? <Chat messages={messages} /> : <NoChat />}
26 <p>ADD A MESSAGE</p>
27 <ChatInput />
28 </div>
29 );
30};
31
32export default ChatSection;
33import { useState } from "react";
34import ChatLine from "./ChatLine";
35import useChatService from "../hooks/useChatService";
36
37const Chat = ({ messages }) => {
38 const [editValue, setEditValue] = useState("");
39 const [editingId, setEditingId] = useState(null);
40
41 const { updateMessage, deleteMessage } = useChatService();
42
43 return (
44 <div>
45 <p>MESSAGES :</p>
46 {messages.map((line) => (
47 <ChatLine
48 key={line.id}
49 line={line}
50 editValue={line.id === editingId ? editValue : ""}
51 setEditValue={setEditValue}
52 editingId={line.id === editingId ? editingId : null}
53 setEditingId={setEditingId}
54 updateMessage={updateMessage}
55 deleteMessage={deleteMessage}
56 />
57 ))}
58 </div>
59 );
60};
61
62export default Chat;
63import { useState } from "react";
64import useChatService from "../hooks/useChatService";
65
66const ChatInput = () => {
67 const [inputValue, setInputValue] = useState("");
68 const { addMessage } = useChatService();
69
70 return (
71 <textarea
72 onKeyPress={(e) => {
73 if (e.key === "Enter") {
74 e.preventDefault();
75 addMessage(inputValue);
76 setInputValue("");
77 }
78 }}
79 placeholder="new message..."
80 onChange={(e) => {
81 setInputValue(e.target.value);
82 }}
83 value={inputValue}
84 autoFocus
85 />
86 );
87};
88
89export default ChatInput;
90import EditMessage from "./EditMessage";
91import { memo } from "react";
92
93const ChatLine = ({
94 line,
95 editValue,
96 setEditValue,
97 editingId,
98 setEditingId,
99 updateMessage,
100 deleteMessage,
101}) => {
102 return (
103 <div>
104 {editingId !== line.id ? (
105 <>
106 <span style={{ marginRight: "20px" }}>{line.id}: </span>
107 <span style={{ marginRight: "20px" }}>[{line.displayName}]</span>
108 <span style={{ marginRight: "20px" }}>{line.message}</span>
109 <button
110 onClick={() => {
111 setEditingId(line.id);
112 setEditValue(line.message);
113 }}
114 >
115 EDIT
116 </button>
117 <button
118 onClick={() => {
119 deleteMessage(line.id);
120 }}
121 >
122 DELETE
123 </button>
124 </>
125 ) : (
126 <EditMessage
127 editValue={editValue}
128 setEditValue={setEditValue}
129 setEditingId={setEditingId}
130 editingId={editingId}
131 updateMessage={updateMessage}
132 />
133 )}
134 </div>
135 );
136};
137
138export default memo(ChatLine);
139import { memo } from "react";
140
141const EditMessage = ({
142 editValue,
143 setEditValue,
144 editingId,
145 setEditingId,
146 updateMessage,
147}) => {
148 return (
149 <div>
150 <textarea
151 onKeyPress={(e) => {
152 if (e.key === "Enter") {
153 // prevent textarea default behaviour (line break on Enter)
154 e.preventDefault();
155 // updating message in DB
156 updateMessage(editValue, setEditValue, editingId, setEditingId);
157 }
158 }}
159 onChange={(e) => setEditValue(e.target.value)}
160 value={editValue}
161 autoFocus
162 />
163 <button
164 onClick={() => {
165 setEditingId(null);
166 setEditValue(null);
167 }}
168 >
169 CANCEL
170 </button>
171 </div>
172 );
173};
174
175export default memo(EditMessage);
176
useChatService.js
:
1import useChatService from "../hooks/useChatService";
2import { useEffect } from "react";
3import Chat from "./Chat";
4import NoChat from "./NoChat";
5import ChatInput from "./ChatInput";
6
7const ChatSection = () => {
8 let unsubscribe;
9 const { getChatAndUnsub, messages } = useChatService();
10
11 useEffect(() => {
12 const getChat = async () => {
13 unsubscribe = await getChatAndUnsub();
14 };
15
16 getChat();
17
18 return () => {
19 unsubscribe?.();
20 };
21 }, []);
22
23 return (
24 <div>
25 {messages.length ? <Chat messages={messages} /> : <NoChat />}
26 <p>ADD A MESSAGE</p>
27 <ChatInput />
28 </div>
29 );
30};
31
32export default ChatSection;
33import { useState } from "react";
34import ChatLine from "./ChatLine";
35import useChatService from "../hooks/useChatService";
36
37const Chat = ({ messages }) => {
38 const [editValue, setEditValue] = useState("");
39 const [editingId, setEditingId] = useState(null);
40
41 const { updateMessage, deleteMessage } = useChatService();
42
43 return (
44 <div>
45 <p>MESSAGES :</p>
46 {messages.map((line) => (
47 <ChatLine
48 key={line.id}
49 line={line}
50 editValue={line.id === editingId ? editValue : ""}
51 setEditValue={setEditValue}
52 editingId={line.id === editingId ? editingId : null}
53 setEditingId={setEditingId}
54 updateMessage={updateMessage}
55 deleteMessage={deleteMessage}
56 />
57 ))}
58 </div>
59 );
60};
61
62export default Chat;
63import { useState } from "react";
64import useChatService from "../hooks/useChatService";
65
66const ChatInput = () => {
67 const [inputValue, setInputValue] = useState("");
68 const { addMessage } = useChatService();
69
70 return (
71 <textarea
72 onKeyPress={(e) => {
73 if (e.key === "Enter") {
74 e.preventDefault();
75 addMessage(inputValue);
76 setInputValue("");
77 }
78 }}
79 placeholder="new message..."
80 onChange={(e) => {
81 setInputValue(e.target.value);
82 }}
83 value={inputValue}
84 autoFocus
85 />
86 );
87};
88
89export default ChatInput;
90import EditMessage from "./EditMessage";
91import { memo } from "react";
92
93const ChatLine = ({
94 line,
95 editValue,
96 setEditValue,
97 editingId,
98 setEditingId,
99 updateMessage,
100 deleteMessage,
101}) => {
102 return (
103 <div>
104 {editingId !== line.id ? (
105 <>
106 <span style={{ marginRight: "20px" }}>{line.id}: </span>
107 <span style={{ marginRight: "20px" }}>[{line.displayName}]</span>
108 <span style={{ marginRight: "20px" }}>{line.message}</span>
109 <button
110 onClick={() => {
111 setEditingId(line.id);
112 setEditValue(line.message);
113 }}
114 >
115 EDIT
116 </button>
117 <button
118 onClick={() => {
119 deleteMessage(line.id);
120 }}
121 >
122 DELETE
123 </button>
124 </>
125 ) : (
126 <EditMessage
127 editValue={editValue}
128 setEditValue={setEditValue}
129 setEditingId={setEditingId}
130 editingId={editingId}
131 updateMessage={updateMessage}
132 />
133 )}
134 </div>
135 );
136};
137
138export default memo(ChatLine);
139import { memo } from "react";
140
141const EditMessage = ({
142 editValue,
143 setEditValue,
144 editingId,
145 setEditingId,
146 updateMessage,
147}) => {
148 return (
149 <div>
150 <textarea
151 onKeyPress={(e) => {
152 if (e.key === "Enter") {
153 // prevent textarea default behaviour (line break on Enter)
154 e.preventDefault();
155 // updating message in DB
156 updateMessage(editValue, setEditValue, editingId, setEditingId);
157 }
158 }}
159 onChange={(e) => setEditValue(e.target.value)}
160 value={editValue}
161 autoFocus
162 />
163 <button
164 onClick={() => {
165 setEditingId(null);
166 setEditValue(null);
167 }}
168 >
169 CANCEL
170 </button>
171 </div>
172 );
173};
174
175export default memo(EditMessage);
176import { useCallback, useState } from "react";
177import {
178 collection,
179 onSnapshot,
180 orderBy,
181 query,
182 serverTimestamp,
183 updateDoc,
184 doc,
185 addDoc,
186 deleteDoc,
187} from "firebase/firestore";
188import { db } from "../firebase/firebase-config";
189
190const useChatService = () => {
191 const [messages, setMessages] = useState([]);
192
193 /**
194 * Get Messages
195 *
196 * @returns {Promise<Unsubscribe>}
197 */
198 const getChatAndUnsub = async () => {
199 const q = query(collection(db, "messages"), orderBy("createdAt"));
200
201 const unsubscribe = onSnapshot(q, (snapshot) => {
202 const data = snapshot.docs.map((doc, index) => {
203 const entry = doc.data();
204
205 return {
206 id: doc.id,
207 message: entry.message,
208 createdAt: entry.createdAt,
209 updatedAt: entry.updatedAt,
210 uid: entry.uid,
211 displayName: entry.displayName,
212 photoURL: entry.photoURL,
213 };
214 });
215
216 setMessages(data);
217 });
218
219 return unsubscribe;
220 };
221
222 /**
223 * Memoized using useCallback
224 */
225 const updateMessage = useCallback(
226 async (editValue, setEditValue, editingId, setEditingId) => {
227 const message = editValue;
228 const id = editingId;
229
230 // resetting state as soon as we press Enter
231 setEditValue("");
232 setEditingId(null);
233
234 try {
235 await updateDoc(doc(db, "messages", id), {
236 message,
237 updatedAt: serverTimestamp(),
238 });
239 } catch (err) {
240 console.log(err);
241 }
242 },
243 []
244 );
245
246 const addMessage = async (inputValue) => {
247 if (!inputValue) {
248 return;
249 }
250 const message = inputValue;
251
252 const messageData = {
253 // hardcoded photoURL, uid, and displayName for demo purposes
254 photoURL:
255 "https://lh3.googleusercontent.com/a/AATXAJwNw_ECd4OhqV0bwAb7l4UqtPYeSrRMpVB7ayxY=s96-c",
256 uid: keyGen(),
257 message,
258 displayName: "John Doe",
259 createdAt: serverTimestamp(),
260 updatedAt: null,
261 };
262
263 try {
264 await addDoc(collection(db, "messages"), messageData);
265 } catch (e) {
266 console.log(e);
267 }
268 };
269
270 /**
271 * Memoized using useCallback
272 */
273 const deleteMessage = useCallback(async (idToDelete) => {
274 if (!idToDelete) {
275 return;
276 }
277 try {
278 await deleteDoc(doc(db, "messages", idToDelete));
279 } catch (err) {
280 console.log(err);
281 }
282 }, []);
283
284 const keyGen = () => {
285 const s = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
286 return Array(20)
287 .join()
288 .split(",")
289 .map(function () {
290 return s.charAt(Math.floor(Math.random() * s.length));
291 })
292 .join("");
293 };
294
295 return {
296 messages,
297 getChatAndUnsub,
298 updateMessage,
299 addMessage,
300 deleteMessage,
301 };
302};
303
304export default useChatService;
305
When a message gets updated using updateMessage
method, I only need the affected ChatLine
to rerender (same for add & delete), not every single ChatLine
in the list, while keeping the messages
state passed from ChatSection
to Chat
, I understand that ChatSection
& Chat
should rerender, but not every ChatLine
in the list. (Also ChatLine
is memoized)
EDIT 1: I guess the problem is with setMessages(data)
in useChatService.js
, but I thought React will only rerender the edited line because I already provided the key={line.id}
when looping through messages
in Chat
component, but I have no idea how to fix this.
ANSWER
Answered 2021-Dec-13 at 23:35This is what I think, You are passing Messages
in ChatSection
and that means that when Messages
get updated ChatSection
will rerender and all its children will rerender too.
So here is my idea remove Messages
from ChatSection
and only add it in Chat
.
You already using useChatService
in Chat so adding Messages
there should be better.
Try this and gets back too us if it working.
If still not as you like it to be there is also other way we could fix it.
But you have to create a working example for us so we could have a look and make small changes.
QUESTION
Google Play App Rejection - Not a core feature - Use of All files access
Asked 2021-Nov-26 at 12:40I have an application on play store to whom the targetSdkVersion
is update to 30
from 29
, which is getting rejected again and again by Google Play after an update.
Previously, there was a permission of MANAGE_EXTERNAL_STORAGE
in one of the SDK Manifest.
After removing MANAGE_EXTERNAL_STORAGE
permission and storage permission (WRITE_EXTERNAL_STORAGE
) completely from my app, uploading the app on store, app update gets rejected again.
This is the email received from Google Play for the rejection reason.
Note: I am saving all my media files in app-specific internal storage.
Also, I have the permission of READ_EXTERNAL_STORAGE
in my SDK as we have chat feature in our app to get images and videos of device to sent it.
According to Use of All files access (MANAGE_EXTERNAL_STORAGE) permission
READ_EXTERNAL_STORAGE
permission has not impact.
Update
I also removed READ_EXTERNAL_STORAGE
permission from the app, but still got the rejection with same reason from Google Play.
Is the issue with Storage Policy, or something else?
ANSWER
Answered 2021-Nov-25 at 13:10I had the same error for a month but finally, Google Play Store accepted my uploads.
Briefly, what I did was to create new builds for each track, and -interestingly- it worked!
(Before my countless update trials, our latest version on Production was 2.23.5 (build 1)
, our active tracks were Internal Testing Track and Production, and I was trying to upload my updates to Internal Testing Track.)
Below are the steps that I've applied:
- Created a new build
2.24.1 (build 1)
with all necessary changes. (e.g. upgradingtargetSdkVersion
to 30, removingMANAGE_EXTERNAL_STORAGE
permission, etc.) - Activated our inactive tracks (Open, Closed Alpha, and Beta Testing Tracks), uploaded the same build
2.24.1 (build 1)
to these tracks, and then paused those tracks. (I've paused them as I won't use them actively, you may not want to pause it) - Created another build
2.24.1 (build 2)
which was completely the same as build 1. I've just updated its build number. - Uploaded
2.24.1 (build 2)
to the Internal Testing Track. - Created another build
2.24.1 (build 3)
which was completely the same as build 3. I've just updated its build number. - Uploaded
2.24.1 (build 3)
to the Production Track. - Went to "Publishing Overview" page, activated Managed Publishing in order to manually publish my uploads to Production and other tracks as they got accepted.
- Sent these uploads to review at once and voila, Google accepts your uploads!
Sarcasm on.
Hereby, I would like to congratulate Google Play Support as they've shared all these details within their documentation, within their rejection e-mails, and within their super fast response to the appeal.
Sarcasm off.
I've found this solution referencing from this answer https://stackoverflow.com/a/69933431/2833718. I couldn't find any help from Google's official docs. They've always rejected my uploads with the same e-mail which is impossible to decode for a human being. They've never returned to my appeal.
This migration and support process was completely a failure.
Thank you Google Play Support, you are everything but support to developers.
QUESTION
How to add count values in venn diagram for more than 6 sets?
Asked 2021-Nov-04 at 00:43I used following code to generate the sets for more than 5 groups:
1library(venneuler)
2
3H=list('ASD'=c("SCN3A", "TSC2", "RASSF8", "XDH", "CNTN5", "CHD7", "DPYD", "BUB1", "DPP4", "AMPD1", "ARID4A", "QSER1", "OCA2", "GPR141", "DNAH9", "LOXHD1", "SETX", "GSTP1", "SLC6A15", "ASTN1", "CACNA1D", "WFS1", "KCNC1", "TPRA1", "NBAS", "LAMB1", "TSNARE1", "GABRB3", "PAG1", "SOS1", "LHFPL4", "KMT2C", "GATM", "NPTX2", "ANK3", "SH3TC2", "CLPP", "TP53BP1", "EBF4", "ANO1", "DNAJC10", "TTC25", "NDUFB7", "PCSK1", "ROBO3", "MYO9A", "RPS23", "ZNF292", "CRBN", "HIVEP2", "CYP1B1", "KCNE2", "NRP2", "ADSL", "XIRP2", "SMARCA4", "HDAC2", "JAK2", "ATP9B", "ESR1", "MDN1", "CTNNA2", "CNTNAP2", "SPTB", "ACY1", "CEP290", "WNT2", "IQGAP3", "CACNG3", "CACNA1H", "FOXN1", "SPAST", "ADCY1", "IGF2", "RNF4", "CTTNBP2", "TMF1", "CPT1A", "TENM3", "RABGGTA", "MBD3", "CCDC18", "SMG1", "SYNE1", "PITX3", "HMGA2", "PDE6C", "CTU2", "PNPLA7", "PIEZO1", "MAP2", "MCF2L", "PRF1", "VWA8", "LRP2", "RYR3", "IPO9", "DIXDC1", "CNTNAP5", "ELP4", "LRRN1", "TRIO", "SACS", "ASIC2", "KIF1B", "AXIN2", "SORL1", "DLG2", "VPS13C", "F2RL1", "NRP1", "LAMA1", "LARP1", "SDK1", "LAMC2", "LSG1", "EP300", "DGCR6L", "TSHB", "APC", "TENM4", "IGSF21"),
4 'Epilepsy'=c("ADCY1", "ADSL", "ANK3", "APC", "ASIC2", "ASTN1", "ATP9B", "AXIN2", "BUB1", "CACNA1D", "CACNA1H", "CACNG3", "CEP290", "CLPP", "CNTN5", "CNTNAP2", "CNTNAP5", "CTNNA2", "CTU2", "DGCR6L", "DLG2", "DNAJC10", "ELP4", "EP300", "GABRB3", "HDAC2", "HMGA2", "IGSF21", "IPO9", "IQGAP3", "JAK2", "KCNC1", "KCNE2", "KIF1B", "LAMB1", "LAMC2", "LARP1", "LHFPL4", "MCF2L", "MYO9A", "NDUFB7", "NRP2", "RABGGTA", "RYR3", "SACS", "SCN3A", "SETX", "SMARCA4", "SMG1", "SORL1", "SPAST", "SPTB", "TMF1", "TP53BP1", "TPRA1", "TRIO", "TSC2", "TSHB", "VPS13C", "WFS1", "XDH", "ZNF292", "ABCA1", "ABCG5", "ACP2", "ADCY6", "ADGRA3", "ADGRV1", "AGA", "AGRN", "ALG3", "ANK2", "ANKRD44", "AP5Z1", "ARAP1", "ARHGEF11", "ASCC3", "ASPM", "ATRN", "AURKB", "BRINP2", "BRSK2", "CAPN15", "CAPN2", "CC2D2A", "CD36", "CDX1", "CHAT", "CHM", "CHTF18", "CLCN2", "CLCN7", "CLEC12A", "COG5", "COG6", "COL12A1", "COL17A1", "COL28A1", "COL6A2", "COQ3", "CYBB", "DBNL", "DBR1", "DEAF1", "DGKQ", "DHX29", "DMXL1", "DMXL2", "DNAH12", "DOCK7", "DOLK", "DSG4", "DZIP1", "EFHC1", "EPHA7", "EPHB1", "EPHB3", "ESYT1", "EXOC7", "F13A1", "F5", "FAH", "FARP1", "FASN", "FAT1", "FERMT1", "FGFR3", "FLNB", "FLRT1", "FMNL1", "FN1", "FOLR1", "FZD4", "GAA", "GAK", "GALC", "GANAB", "GLB1", "GM2A", "GNA14", "GOSR2", "GPC1", "GSS", "GTPBP4", "HEATR1", "HGS", "HIPK2", "HSPA13", "HTR2B", "INO80E", "KALRN", "KCNH2", "KCNJ16", "KIAA0586", "KRIT1", "LAMB2", "LMAN1", "LTBP3", "MASTL", "MED17", "METTL25", "MGAT5B", "MPL", "MRPL24", "MRPS27", "MSX2", "MUS81", "NALCN", "NEB", "NFE2L1", "NMBR", "NOL11", "NUCB1", "OBSL1", "OGDHL", "OGFOD2", "PARP1", "PCCB", "PDGFRA", "PDYN", "PFAS", "PFKFB3", "PLEC", "PLOD2", "PNKD", "PNPO", "POLD1", "POLE", "POLL", "PPAT", "PRDX3", "PSEN2", "PTCH1", "PTK2B", "RAB5A", "RAD54B", "RELB", "RHOT2", "RIMS2", "RTN4IP1", "SAE1", "SCAPER", "SCN1B", "SCN5A", "SEC23IP", "SERPINE2", "SGCB", "SIGLEC1", "SLC18A3", "SLC26A4", "SLC2A1", "SLC4A1", "SLC4A3", "SLITRK6", "SPG11", "STARD13", "STT3A", "SYF2", "SYNJ1", "SZT2", "TECPR2", "TES", "TMEM67", "TNK2", "TNS1", "TNS3", "TRAP1", "TRAPPC11", "TRAPPC8", "TRIP10", "TRPM2", "TRPM3", "TRPV1", "TUBGCP6", "TYW1", "UNC13B", "USP45", "VCP", "WDR62", "WWOX", "YAP1", "ZBTB48", "ZFHX4", "ZW10"),
5 'Intellectual'=c("YAP1", "TSC2", "FMNL1", "MADD", "KRIT1", "TNK2", "NUP155", "COG6", "TRAPPC8", "IPO9", "CCT8", "ZFYVE16", "FAT1", "SLC37A1", "KAT6B", "WWOX", "PTK2B", "CNTNAP5", "HEATR1", "TRAPPC11", "ARID4A", "ADGRV1", "GPC1", "AURKB", "TTC39B", "GSS", "GANAB", "RFWD3", "CUL9", "SAE1", "CACNG3", "SMC4", "ASIC2", "SYF2", "PFAS", "GAK", "METTL25", "OGDHL", "RAB5A", "VPS13C", "FGFR3", "KCNC1", "DDOST", "CTNND1", "ATRN", "UNC13B", "FASN", "MYO18A", "TMF1", "CRBN", "FLNB", "LARP1", "RCC2", "MASTL", "ADGRA3", "SCAPER", "SZT2", "LRP4", "SMG1", "SYNE1", "ADCY6", "RNGTT", "EP300", "ARAP1", "ANKRD44", "VPS39", "DGCR6L", "STT3A", "COG5", "NFE2L1", "SLC7A2", "ASCC3", "LMAN1", "OBSL1", "KIF20B", "PNPLA7"),
6 'Schizophrenia'=c("CRB1", "FBXW4", "CNTN5", "CHM", "DPYD", "BUB1", "DPP4", "ADGRV1", "GPC1", "DLD", "RBM19", "ITIH1", "ADCY7", "KCNC1", "ACBD5", "ELF1", "TSNARE1", "GABRB3", "TMEM182", "STT3A", "KMT2C", "ANK3", "SAMD4A", "NALCN", "PDLIM5", "LIMA1", "DYNC1I2", "TMEM26", "ANK2", "GRIN3A", "EPHB1", "BRINP2", "KALRN", "MICAL2", "TTLL6", "ZNF292", "SERPINB1", "SCAPER", "KCNS3", "VAMP1", "HDAC2", "DLG1", "CFAP58", "JAK2", "ESR1", "EFCAB14", "CNTNAP2", "PENK", "WWOX", "GLT8D1", "SFMBT2", "EEFSEC", "PDZD8", "GALC", "CACNG3", "SPG7", "ADCY1", "CLDN10", "TENM3", "OTOS", "CAPN2", "LRP4", "SYNE1", "HMGA2", "APOL4", "ARAP1", "DOPEY1", "EPN2", "MCF2L", "PLAA", "RYR3", "CNTNAP5", "POLE", "TRIO", "RAB11FIP5", "BNIP3L", "RUNX1", "AXIN2", "KIF1B", "DLG2", "MAP3K9", "CERCAM", "VPS13C", "MYO18B", "NRP1", "IRS1", "MANEA", "EP300", "DGCR6L", "TSHB", "AASDHPPT", "TRAPPC3", "APC", "TENM4"),
7 'ADHD'=c("TSC2", "CSMD2", "ANK3", "ASPM", "CNTN5", "TP53BP1", "CNTNAP2", "CHD7", "GLT8D1", "CNTNAP5", "SFMBT2", "MLH1", "FLII", "PTCH1", "SPRED1", "ARHGEF12", "CHMP7", "SVEP1", "CREB5", "MSH6", "TTLL8", "DLG2", "MICAL2", "DNAH3", "ADGRA3", "ACBD5", "SYNE1", "NUCB1", "NRP2", "TMEM182", "STT3A", "GNE", "PAX5", "TENM4"),
8 'Biopolar Disoder'=c("CSMD2", "ANK3", "NUMB", "CNTN5", "CTNNA2", "CNTNAP2", "NALCN", "RDH14", "WWOX", "GLT8D1", "SFMBT2", "SPRED1", "ADAMTS14", "TTC39B", "SVEP1", "COL28A1", "PDZD8", "GALC", "SORL1", "ITIH1", "CLSPN", "SLCO4A1", "VPS13C", "MYO18B", "TTLL6", "CRBN", "NFATC2", "SYNE1", "INTS7", "TMEM182", "STT3A", "WSCD1", "KCNS3", "PDGFRA"),
9 'circadian'=c("YTHDC2", "LRP1B", "SAMD4A", "VTA1", "NALCN", "F13A1", "SLC4A1", "TMEM26", "ADAMTS14", "COL28A1", "RNF19A", "BRINP2", "TRHR", "CCBE1", "CACNA2D3", "MYO18A", "SLC26A7", "FRAS1", "EP300", "GNE", "LMAN1", "NMBR", "TGFBI", "CHAT", "HIPK2", "SERPINE2", "RELB", "ARHGEF12", "SETX", "CACNA1D", "ADCY7", "NBAS", "GPR83", "LTBP3", "GABRB3", "HMBS", "PSMA4", "MADD", "SIX3", "EPHB1", "GAK", "SPRY4", "ABCA13", "SLC8A3", "HIVEP2", "FAH", "ADCY6", "MYLIP", "NFE2L1", "PRKAG1", "HDAC2", "TNS1", "GSS", "CACNA1H", "POLL", "CPT1A", "CAPN2", "PITX3", "NFE2L3", "PNPLA7", "AGA", "STX16", "TNK2", "PRF1", "RYR3", "DIXDC1", "PSEN2", "SREBF1", "POLE", "RAB11FIP5", "KIF1B", "RAB5A", "NGB", "ARHGEF11", "SIX6", "SDK1", "AATK", "CYP7A1", "CUL9"),
10 'dementia'=c("LMAN1", "PRDX3", "NPLOC4", "PSEN2", "ZFYVE16", "CHAT", "PENK", "LTBP1", "SNCAIP", "NOL11", "GANAB", "DLD", "SPG11", "IGSF21", "RNF19A", "ASIC2", "ASTN1", "SORL1", "SPRY4", "VCP", "TATDN1", "RAB5A", "VPS13C", "GM2A", "IRS1", "PSMB4", "NGB", "F2RL1", "RAB38", "SMOX", "PARP1", "ABCC9", "RPN2", "CAPN2", "GALNT7", "SMG1", "TBK1", "MASP2", "GNE", "GTPBP4", "CCT8", "CD63", "PSMA4", "TUBA4A", "CUL9")
11 )
12
13Hmat <- lapply(seq_along(H), \(i) {
14Set <- names(H)[i]
15data.frame(Element = H[[i]], Set)
16 })
17Hmat <- do.call(rbind, Hmat)
18vd <- venneuler(Hmat)
19plot(vd)
20
ANSWER
Answered 2021-Nov-04 at 00:43Change vd
's label manually will help.
1library(venneuler)
2
3H=list('ASD'=c("SCN3A", "TSC2", "RASSF8", "XDH", "CNTN5", "CHD7", "DPYD", "BUB1", "DPP4", "AMPD1", "ARID4A", "QSER1", "OCA2", "GPR141", "DNAH9", "LOXHD1", "SETX", "GSTP1", "SLC6A15", "ASTN1", "CACNA1D", "WFS1", "KCNC1", "TPRA1", "NBAS", "LAMB1", "TSNARE1", "GABRB3", "PAG1", "SOS1", "LHFPL4", "KMT2C", "GATM", "NPTX2", "ANK3", "SH3TC2", "CLPP", "TP53BP1", "EBF4", "ANO1", "DNAJC10", "TTC25", "NDUFB7", "PCSK1", "ROBO3", "MYO9A", "RPS23", "ZNF292", "CRBN", "HIVEP2", "CYP1B1", "KCNE2", "NRP2", "ADSL", "XIRP2", "SMARCA4", "HDAC2", "JAK2", "ATP9B", "ESR1", "MDN1", "CTNNA2", "CNTNAP2", "SPTB", "ACY1", "CEP290", "WNT2", "IQGAP3", "CACNG3", "CACNA1H", "FOXN1", "SPAST", "ADCY1", "IGF2", "RNF4", "CTTNBP2", "TMF1", "CPT1A", "TENM3", "RABGGTA", "MBD3", "CCDC18", "SMG1", "SYNE1", "PITX3", "HMGA2", "PDE6C", "CTU2", "PNPLA7", "PIEZO1", "MAP2", "MCF2L", "PRF1", "VWA8", "LRP2", "RYR3", "IPO9", "DIXDC1", "CNTNAP5", "ELP4", "LRRN1", "TRIO", "SACS", "ASIC2", "KIF1B", "AXIN2", "SORL1", "DLG2", "VPS13C", "F2RL1", "NRP1", "LAMA1", "LARP1", "SDK1", "LAMC2", "LSG1", "EP300", "DGCR6L", "TSHB", "APC", "TENM4", "IGSF21"),
4 'Epilepsy'=c("ADCY1", "ADSL", "ANK3", "APC", "ASIC2", "ASTN1", "ATP9B", "AXIN2", "BUB1", "CACNA1D", "CACNA1H", "CACNG3", "CEP290", "CLPP", "CNTN5", "CNTNAP2", "CNTNAP5", "CTNNA2", "CTU2", "DGCR6L", "DLG2", "DNAJC10", "ELP4", "EP300", "GABRB3", "HDAC2", "HMGA2", "IGSF21", "IPO9", "IQGAP3", "JAK2", "KCNC1", "KCNE2", "KIF1B", "LAMB1", "LAMC2", "LARP1", "LHFPL4", "MCF2L", "MYO9A", "NDUFB7", "NRP2", "RABGGTA", "RYR3", "SACS", "SCN3A", "SETX", "SMARCA4", "SMG1", "SORL1", "SPAST", "SPTB", "TMF1", "TP53BP1", "TPRA1", "TRIO", "TSC2", "TSHB", "VPS13C", "WFS1", "XDH", "ZNF292", "ABCA1", "ABCG5", "ACP2", "ADCY6", "ADGRA3", "ADGRV1", "AGA", "AGRN", "ALG3", "ANK2", "ANKRD44", "AP5Z1", "ARAP1", "ARHGEF11", "ASCC3", "ASPM", "ATRN", "AURKB", "BRINP2", "BRSK2", "CAPN15", "CAPN2", "CC2D2A", "CD36", "CDX1", "CHAT", "CHM", "CHTF18", "CLCN2", "CLCN7", "CLEC12A", "COG5", "COG6", "COL12A1", "COL17A1", "COL28A1", "COL6A2", "COQ3", "CYBB", "DBNL", "DBR1", "DEAF1", "DGKQ", "DHX29", "DMXL1", "DMXL2", "DNAH12", "DOCK7", "DOLK", "DSG4", "DZIP1", "EFHC1", "EPHA7", "EPHB1", "EPHB3", "ESYT1", "EXOC7", "F13A1", "F5", "FAH", "FARP1", "FASN", "FAT1", "FERMT1", "FGFR3", "FLNB", "FLRT1", "FMNL1", "FN1", "FOLR1", "FZD4", "GAA", "GAK", "GALC", "GANAB", "GLB1", "GM2A", "GNA14", "GOSR2", "GPC1", "GSS", "GTPBP4", "HEATR1", "HGS", "HIPK2", "HSPA13", "HTR2B", "INO80E", "KALRN", "KCNH2", "KCNJ16", "KIAA0586", "KRIT1", "LAMB2", "LMAN1", "LTBP3", "MASTL", "MED17", "METTL25", "MGAT5B", "MPL", "MRPL24", "MRPS27", "MSX2", "MUS81", "NALCN", "NEB", "NFE2L1", "NMBR", "NOL11", "NUCB1", "OBSL1", "OGDHL", "OGFOD2", "PARP1", "PCCB", "PDGFRA", "PDYN", "PFAS", "PFKFB3", "PLEC", "PLOD2", "PNKD", "PNPO", "POLD1", "POLE", "POLL", "PPAT", "PRDX3", "PSEN2", "PTCH1", "PTK2B", "RAB5A", "RAD54B", "RELB", "RHOT2", "RIMS2", "RTN4IP1", "SAE1", "SCAPER", "SCN1B", "SCN5A", "SEC23IP", "SERPINE2", "SGCB", "SIGLEC1", "SLC18A3", "SLC26A4", "SLC2A1", "SLC4A1", "SLC4A3", "SLITRK6", "SPG11", "STARD13", "STT3A", "SYF2", "SYNJ1", "SZT2", "TECPR2", "TES", "TMEM67", "TNK2", "TNS1", "TNS3", "TRAP1", "TRAPPC11", "TRAPPC8", "TRIP10", "TRPM2", "TRPM3", "TRPV1", "TUBGCP6", "TYW1", "UNC13B", "USP45", "VCP", "WDR62", "WWOX", "YAP1", "ZBTB48", "ZFHX4", "ZW10"),
5 'Intellectual'=c("YAP1", "TSC2", "FMNL1", "MADD", "KRIT1", "TNK2", "NUP155", "COG6", "TRAPPC8", "IPO9", "CCT8", "ZFYVE16", "FAT1", "SLC37A1", "KAT6B", "WWOX", "PTK2B", "CNTNAP5", "HEATR1", "TRAPPC11", "ARID4A", "ADGRV1", "GPC1", "AURKB", "TTC39B", "GSS", "GANAB", "RFWD3", "CUL9", "SAE1", "CACNG3", "SMC4", "ASIC2", "SYF2", "PFAS", "GAK", "METTL25", "OGDHL", "RAB5A", "VPS13C", "FGFR3", "KCNC1", "DDOST", "CTNND1", "ATRN", "UNC13B", "FASN", "MYO18A", "TMF1", "CRBN", "FLNB", "LARP1", "RCC2", "MASTL", "ADGRA3", "SCAPER", "SZT2", "LRP4", "SMG1", "SYNE1", "ADCY6", "RNGTT", "EP300", "ARAP1", "ANKRD44", "VPS39", "DGCR6L", "STT3A", "COG5", "NFE2L1", "SLC7A2", "ASCC3", "LMAN1", "OBSL1", "KIF20B", "PNPLA7"),
6 'Schizophrenia'=c("CRB1", "FBXW4", "CNTN5", "CHM", "DPYD", "BUB1", "DPP4", "ADGRV1", "GPC1", "DLD", "RBM19", "ITIH1", "ADCY7", "KCNC1", "ACBD5", "ELF1", "TSNARE1", "GABRB3", "TMEM182", "STT3A", "KMT2C", "ANK3", "SAMD4A", "NALCN", "PDLIM5", "LIMA1", "DYNC1I2", "TMEM26", "ANK2", "GRIN3A", "EPHB1", "BRINP2", "KALRN", "MICAL2", "TTLL6", "ZNF292", "SERPINB1", "SCAPER", "KCNS3", "VAMP1", "HDAC2", "DLG1", "CFAP58", "JAK2", "ESR1", "EFCAB14", "CNTNAP2", "PENK", "WWOX", "GLT8D1", "SFMBT2", "EEFSEC", "PDZD8", "GALC", "CACNG3", "SPG7", "ADCY1", "CLDN10", "TENM3", "OTOS", "CAPN2", "LRP4", "SYNE1", "HMGA2", "APOL4", "ARAP1", "DOPEY1", "EPN2", "MCF2L", "PLAA", "RYR3", "CNTNAP5", "POLE", "TRIO", "RAB11FIP5", "BNIP3L", "RUNX1", "AXIN2", "KIF1B", "DLG2", "MAP3K9", "CERCAM", "VPS13C", "MYO18B", "NRP1", "IRS1", "MANEA", "EP300", "DGCR6L", "TSHB", "AASDHPPT", "TRAPPC3", "APC", "TENM4"),
7 'ADHD'=c("TSC2", "CSMD2", "ANK3", "ASPM", "CNTN5", "TP53BP1", "CNTNAP2", "CHD7", "GLT8D1", "CNTNAP5", "SFMBT2", "MLH1", "FLII", "PTCH1", "SPRED1", "ARHGEF12", "CHMP7", "SVEP1", "CREB5", "MSH6", "TTLL8", "DLG2", "MICAL2", "DNAH3", "ADGRA3", "ACBD5", "SYNE1", "NUCB1", "NRP2", "TMEM182", "STT3A", "GNE", "PAX5", "TENM4"),
8 'Biopolar Disoder'=c("CSMD2", "ANK3", "NUMB", "CNTN5", "CTNNA2", "CNTNAP2", "NALCN", "RDH14", "WWOX", "GLT8D1", "SFMBT2", "SPRED1", "ADAMTS14", "TTC39B", "SVEP1", "COL28A1", "PDZD8", "GALC", "SORL1", "ITIH1", "CLSPN", "SLCO4A1", "VPS13C", "MYO18B", "TTLL6", "CRBN", "NFATC2", "SYNE1", "INTS7", "TMEM182", "STT3A", "WSCD1", "KCNS3", "PDGFRA"),
9 'circadian'=c("YTHDC2", "LRP1B", "SAMD4A", "VTA1", "NALCN", "F13A1", "SLC4A1", "TMEM26", "ADAMTS14", "COL28A1", "RNF19A", "BRINP2", "TRHR", "CCBE1", "CACNA2D3", "MYO18A", "SLC26A7", "FRAS1", "EP300", "GNE", "LMAN1", "NMBR", "TGFBI", "CHAT", "HIPK2", "SERPINE2", "RELB", "ARHGEF12", "SETX", "CACNA1D", "ADCY7", "NBAS", "GPR83", "LTBP3", "GABRB3", "HMBS", "PSMA4", "MADD", "SIX3", "EPHB1", "GAK", "SPRY4", "ABCA13", "SLC8A3", "HIVEP2", "FAH", "ADCY6", "MYLIP", "NFE2L1", "PRKAG1", "HDAC2", "TNS1", "GSS", "CACNA1H", "POLL", "CPT1A", "CAPN2", "PITX3", "NFE2L3", "PNPLA7", "AGA", "STX16", "TNK2", "PRF1", "RYR3", "DIXDC1", "PSEN2", "SREBF1", "POLE", "RAB11FIP5", "KIF1B", "RAB5A", "NGB", "ARHGEF11", "SIX6", "SDK1", "AATK", "CYP7A1", "CUL9"),
10 'dementia'=c("LMAN1", "PRDX3", "NPLOC4", "PSEN2", "ZFYVE16", "CHAT", "PENK", "LTBP1", "SNCAIP", "NOL11", "GANAB", "DLD", "SPG11", "IGSF21", "RNF19A", "ASIC2", "ASTN1", "SORL1", "SPRY4", "VCP", "TATDN1", "RAB5A", "VPS13C", "GM2A", "IRS1", "PSMB4", "NGB", "F2RL1", "RAB38", "SMOX", "PARP1", "ABCC9", "RPN2", "CAPN2", "GALNT7", "SMG1", "TBK1", "MASP2", "GNE", "GTPBP4", "CCT8", "CD63", "PSMA4", "TUBA4A", "CUL9")
11 )
12
13Hmat <- lapply(seq_along(H), \(i) {
14Set <- names(H)[i]
15data.frame(Element = H[[i]], Set)
16 })
17Hmat <- do.call(rbind, Hmat)
18vd <- venneuler(Hmat)
19plot(vd)
20HH <- Hmat %>%
21 group_by(Set) %>%
22 summarise(n = n()) %>%
23 .[match(vd$labels, .$Set),] %>%
24 mutate(n = paste(Set, "\n", n))
25vd$labels <- HH$n
26plot(vd)
27
1library(venneuler)
2
3H=list('ASD'=c("SCN3A", "TSC2", "RASSF8", "XDH", "CNTN5", "CHD7", "DPYD", "BUB1", "DPP4", "AMPD1", "ARID4A", "QSER1", "OCA2", "GPR141", "DNAH9", "LOXHD1", "SETX", "GSTP1", "SLC6A15", "ASTN1", "CACNA1D", "WFS1", "KCNC1", "TPRA1", "NBAS", "LAMB1", "TSNARE1", "GABRB3", "PAG1", "SOS1", "LHFPL4", "KMT2C", "GATM", "NPTX2", "ANK3", "SH3TC2", "CLPP", "TP53BP1", "EBF4", "ANO1", "DNAJC10", "TTC25", "NDUFB7", "PCSK1", "ROBO3", "MYO9A", "RPS23", "ZNF292", "CRBN", "HIVEP2", "CYP1B1", "KCNE2", "NRP2", "ADSL", "XIRP2", "SMARCA4", "HDAC2", "JAK2", "ATP9B", "ESR1", "MDN1", "CTNNA2", "CNTNAP2", "SPTB", "ACY1", "CEP290", "WNT2", "IQGAP3", "CACNG3", "CACNA1H", "FOXN1", "SPAST", "ADCY1", "IGF2", "RNF4", "CTTNBP2", "TMF1", "CPT1A", "TENM3", "RABGGTA", "MBD3", "CCDC18", "SMG1", "SYNE1", "PITX3", "HMGA2", "PDE6C", "CTU2", "PNPLA7", "PIEZO1", "MAP2", "MCF2L", "PRF1", "VWA8", "LRP2", "RYR3", "IPO9", "DIXDC1", "CNTNAP5", "ELP4", "LRRN1", "TRIO", "SACS", "ASIC2", "KIF1B", "AXIN2", "SORL1", "DLG2", "VPS13C", "F2RL1", "NRP1", "LAMA1", "LARP1", "SDK1", "LAMC2", "LSG1", "EP300", "DGCR6L", "TSHB", "APC", "TENM4", "IGSF21"),
4 'Epilepsy'=c("ADCY1", "ADSL", "ANK3", "APC", "ASIC2", "ASTN1", "ATP9B", "AXIN2", "BUB1", "CACNA1D", "CACNA1H", "CACNG3", "CEP290", "CLPP", "CNTN5", "CNTNAP2", "CNTNAP5", "CTNNA2", "CTU2", "DGCR6L", "DLG2", "DNAJC10", "ELP4", "EP300", "GABRB3", "HDAC2", "HMGA2", "IGSF21", "IPO9", "IQGAP3", "JAK2", "KCNC1", "KCNE2", "KIF1B", "LAMB1", "LAMC2", "LARP1", "LHFPL4", "MCF2L", "MYO9A", "NDUFB7", "NRP2", "RABGGTA", "RYR3", "SACS", "SCN3A", "SETX", "SMARCA4", "SMG1", "SORL1", "SPAST", "SPTB", "TMF1", "TP53BP1", "TPRA1", "TRIO", "TSC2", "TSHB", "VPS13C", "WFS1", "XDH", "ZNF292", "ABCA1", "ABCG5", "ACP2", "ADCY6", "ADGRA3", "ADGRV1", "AGA", "AGRN", "ALG3", "ANK2", "ANKRD44", "AP5Z1", "ARAP1", "ARHGEF11", "ASCC3", "ASPM", "ATRN", "AURKB", "BRINP2", "BRSK2", "CAPN15", "CAPN2", "CC2D2A", "CD36", "CDX1", "CHAT", "CHM", "CHTF18", "CLCN2", "CLCN7", "CLEC12A", "COG5", "COG6", "COL12A1", "COL17A1", "COL28A1", "COL6A2", "COQ3", "CYBB", "DBNL", "DBR1", "DEAF1", "DGKQ", "DHX29", "DMXL1", "DMXL2", "DNAH12", "DOCK7", "DOLK", "DSG4", "DZIP1", "EFHC1", "EPHA7", "EPHB1", "EPHB3", "ESYT1", "EXOC7", "F13A1", "F5", "FAH", "FARP1", "FASN", "FAT1", "FERMT1", "FGFR3", "FLNB", "FLRT1", "FMNL1", "FN1", "FOLR1", "FZD4", "GAA", "GAK", "GALC", "GANAB", "GLB1", "GM2A", "GNA14", "GOSR2", "GPC1", "GSS", "GTPBP4", "HEATR1", "HGS", "HIPK2", "HSPA13", "HTR2B", "INO80E", "KALRN", "KCNH2", "KCNJ16", "KIAA0586", "KRIT1", "LAMB2", "LMAN1", "LTBP3", "MASTL", "MED17", "METTL25", "MGAT5B", "MPL", "MRPL24", "MRPS27", "MSX2", "MUS81", "NALCN", "NEB", "NFE2L1", "NMBR", "NOL11", "NUCB1", "OBSL1", "OGDHL", "OGFOD2", "PARP1", "PCCB", "PDGFRA", "PDYN", "PFAS", "PFKFB3", "PLEC", "PLOD2", "PNKD", "PNPO", "POLD1", "POLE", "POLL", "PPAT", "PRDX3", "PSEN2", "PTCH1", "PTK2B", "RAB5A", "RAD54B", "RELB", "RHOT2", "RIMS2", "RTN4IP1", "SAE1", "SCAPER", "SCN1B", "SCN5A", "SEC23IP", "SERPINE2", "SGCB", "SIGLEC1", "SLC18A3", "SLC26A4", "SLC2A1", "SLC4A1", "SLC4A3", "SLITRK6", "SPG11", "STARD13", "STT3A", "SYF2", "SYNJ1", "SZT2", "TECPR2", "TES", "TMEM67", "TNK2", "TNS1", "TNS3", "TRAP1", "TRAPPC11", "TRAPPC8", "TRIP10", "TRPM2", "TRPM3", "TRPV1", "TUBGCP6", "TYW1", "UNC13B", "USP45", "VCP", "WDR62", "WWOX", "YAP1", "ZBTB48", "ZFHX4", "ZW10"),
5 'Intellectual'=c("YAP1", "TSC2", "FMNL1", "MADD", "KRIT1", "TNK2", "NUP155", "COG6", "TRAPPC8", "IPO9", "CCT8", "ZFYVE16", "FAT1", "SLC37A1", "KAT6B", "WWOX", "PTK2B", "CNTNAP5", "HEATR1", "TRAPPC11", "ARID4A", "ADGRV1", "GPC1", "AURKB", "TTC39B", "GSS", "GANAB", "RFWD3", "CUL9", "SAE1", "CACNG3", "SMC4", "ASIC2", "SYF2", "PFAS", "GAK", "METTL25", "OGDHL", "RAB5A", "VPS13C", "FGFR3", "KCNC1", "DDOST", "CTNND1", "ATRN", "UNC13B", "FASN", "MYO18A", "TMF1", "CRBN", "FLNB", "LARP1", "RCC2", "MASTL", "ADGRA3", "SCAPER", "SZT2", "LRP4", "SMG1", "SYNE1", "ADCY6", "RNGTT", "EP300", "ARAP1", "ANKRD44", "VPS39", "DGCR6L", "STT3A", "COG5", "NFE2L1", "SLC7A2", "ASCC3", "LMAN1", "OBSL1", "KIF20B", "PNPLA7"),
6 'Schizophrenia'=c("CRB1", "FBXW4", "CNTN5", "CHM", "DPYD", "BUB1", "DPP4", "ADGRV1", "GPC1", "DLD", "RBM19", "ITIH1", "ADCY7", "KCNC1", "ACBD5", "ELF1", "TSNARE1", "GABRB3", "TMEM182", "STT3A", "KMT2C", "ANK3", "SAMD4A", "NALCN", "PDLIM5", "LIMA1", "DYNC1I2", "TMEM26", "ANK2", "GRIN3A", "EPHB1", "BRINP2", "KALRN", "MICAL2", "TTLL6", "ZNF292", "SERPINB1", "SCAPER", "KCNS3", "VAMP1", "HDAC2", "DLG1", "CFAP58", "JAK2", "ESR1", "EFCAB14", "CNTNAP2", "PENK", "WWOX", "GLT8D1", "SFMBT2", "EEFSEC", "PDZD8", "GALC", "CACNG3", "SPG7", "ADCY1", "CLDN10", "TENM3", "OTOS", "CAPN2", "LRP4", "SYNE1", "HMGA2", "APOL4", "ARAP1", "DOPEY1", "EPN2", "MCF2L", "PLAA", "RYR3", "CNTNAP5", "POLE", "TRIO", "RAB11FIP5", "BNIP3L", "RUNX1", "AXIN2", "KIF1B", "DLG2", "MAP3K9", "CERCAM", "VPS13C", "MYO18B", "NRP1", "IRS1", "MANEA", "EP300", "DGCR6L", "TSHB", "AASDHPPT", "TRAPPC3", "APC", "TENM4"),
7 'ADHD'=c("TSC2", "CSMD2", "ANK3", "ASPM", "CNTN5", "TP53BP1", "CNTNAP2", "CHD7", "GLT8D1", "CNTNAP5", "SFMBT2", "MLH1", "FLII", "PTCH1", "SPRED1", "ARHGEF12", "CHMP7", "SVEP1", "CREB5", "MSH6", "TTLL8", "DLG2", "MICAL2", "DNAH3", "ADGRA3", "ACBD5", "SYNE1", "NUCB1", "NRP2", "TMEM182", "STT3A", "GNE", "PAX5", "TENM4"),
8 'Biopolar Disoder'=c("CSMD2", "ANK3", "NUMB", "CNTN5", "CTNNA2", "CNTNAP2", "NALCN", "RDH14", "WWOX", "GLT8D1", "SFMBT2", "SPRED1", "ADAMTS14", "TTC39B", "SVEP1", "COL28A1", "PDZD8", "GALC", "SORL1", "ITIH1", "CLSPN", "SLCO4A1", "VPS13C", "MYO18B", "TTLL6", "CRBN", "NFATC2", "SYNE1", "INTS7", "TMEM182", "STT3A", "WSCD1", "KCNS3", "PDGFRA"),
9 'circadian'=c("YTHDC2", "LRP1B", "SAMD4A", "VTA1", "NALCN", "F13A1", "SLC4A1", "TMEM26", "ADAMTS14", "COL28A1", "RNF19A", "BRINP2", "TRHR", "CCBE1", "CACNA2D3", "MYO18A", "SLC26A7", "FRAS1", "EP300", "GNE", "LMAN1", "NMBR", "TGFBI", "CHAT", "HIPK2", "SERPINE2", "RELB", "ARHGEF12", "SETX", "CACNA1D", "ADCY7", "NBAS", "GPR83", "LTBP3", "GABRB3", "HMBS", "PSMA4", "MADD", "SIX3", "EPHB1", "GAK", "SPRY4", "ABCA13", "SLC8A3", "HIVEP2", "FAH", "ADCY6", "MYLIP", "NFE2L1", "PRKAG1", "HDAC2", "TNS1", "GSS", "CACNA1H", "POLL", "CPT1A", "CAPN2", "PITX3", "NFE2L3", "PNPLA7", "AGA", "STX16", "TNK2", "PRF1", "RYR3", "DIXDC1", "PSEN2", "SREBF1", "POLE", "RAB11FIP5", "KIF1B", "RAB5A", "NGB", "ARHGEF11", "SIX6", "SDK1", "AATK", "CYP7A1", "CUL9"),
10 'dementia'=c("LMAN1", "PRDX3", "NPLOC4", "PSEN2", "ZFYVE16", "CHAT", "PENK", "LTBP1", "SNCAIP", "NOL11", "GANAB", "DLD", "SPG11", "IGSF21", "RNF19A", "ASIC2", "ASTN1", "SORL1", "SPRY4", "VCP", "TATDN1", "RAB5A", "VPS13C", "GM2A", "IRS1", "PSMB4", "NGB", "F2RL1", "RAB38", "SMOX", "PARP1", "ABCC9", "RPN2", "CAPN2", "GALNT7", "SMG1", "TBK1", "MASP2", "GNE", "GTPBP4", "CCT8", "CD63", "PSMA4", "TUBA4A", "CUL9")
11 )
12
13Hmat <- lapply(seq_along(H), \(i) {
14Set <- names(H)[i]
15data.frame(Element = H[[i]], Set)
16 })
17Hmat <- do.call(rbind, Hmat)
18vd <- venneuler(Hmat)
19plot(vd)
20HH <- Hmat %>%
21 group_by(Set) %>%
22 summarise(n = n()) %>%
23 .[match(vd$labels, .$Set),] %>%
24 mutate(n = paste(Set, "\n", n))
25vd$labels <- HH$n
26plot(vd)
27library(reshape2)
28library(eulerr)
29library(purrr)
30vennfun <- function(x) {
31 x$id <- seq(1, nrow(x)) #add a column of numbers (required for melt)
32 xm <- melt(x, id.vars="id", na.rm=TRUE) #melt table into two columns (value & variable)
33 xc <- dcast(xm, value~variable, fun.aggregate=length) #remove NA's, list presence/absence of each value for each variable (1 or 0)
34 rownames(xc) <- xc$value #value column = rownames (required for Venneuler)
35 xc$value <- NULL #remove redundent value column
36 xc #output the new dataframe
37}
38
39HHH<- as.data.frame(t(map_dfr(H, ~as_data_frame(t(.)))))
40HHHH <- vennfun(HHH)
41plot(eulerr::euler(HHHH), quantities = TRUE)
42
QUESTION
What do the values for gitlab's predefiner variable CI_PIPELINE_SOURCE mean?
Asked 2021-Oct-27 at 08:17In the gitlab documentation you find a list of predefined variables HERE, where the variable CI_PIPELINE_SOURCE
is explained to have the possible values "push, web, schedule, api, external, chat, webide, merge_request_event, external_pull_request_event, parent_pipeline, trigger, or pipeline."
However, it is not explained, what they mean.
- push: When you push something to a branch?
- web: When you trigger a pipeline from the web GUI?
- schedule: When a pipeline is triggered by a schedule
- api: When the pipeline is triggered by an API request
- external: ???
- chat: ???
- webide: ???
- merge_request_event: Seems to be triggered when a merge request is created. Does not trigger when a change is actually merged
- external_pull_request_event: ???
- parent_pipeline: ???
- trigger: ???
- pipeline: another pipeline?
If someone knows where the documentation for that is hiding, I appreciate if you can let me know where to find it.
In addition, how can I figure out when some changes are actually merged into a branch? How can I trigger a pipeline in that event?
ANSWER
Answered 2021-Oct-27 at 08:17Regarding your first set of questions, i have to point you forward to the gitlab CI Documentation and the rules:if
section. They have their a good explanation of the states and also some addtion https://docs.gitlab.com/ee/ci/jobs/job_control.html#common-if-clauses-for-rules - i am just screenshoting this, so people can relate to it in the future if the link gets outdated:
Regarding your additional question:
A merge is a push. We do not check on some branches for CI_PIPELINE_SOURCE
but for the branch name and do checks simply against that like:
1 rules:
2 - if: '$CI_COMMIT_BRANCH == "master"'
3 - if: '$CI_COMMIT_BRANCH == "develop"'
4 - if: '$CI_COMMIT_BRANCH =~ /^release.*$/i'
5 - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
6
This works eg perfectly in our case for gitflow. But you can vary your rules and easily define them to your own needs - the rules documentation gives a lot of good examples see: https://docs.gitlab.com/ee/ci/jobs/job_control.html#common-if-clauses-for-rules
Community Discussions contain sources that include Stack Exchange Network
Tutorials and Learning Resources in Chat
Tutorials and Learning Resources are not available at this moment for Chat