Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
YDL-Component-Medical
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
杨凯
YDL-Component-Medical
Commits
e9424c46
Commit
e9424c46
authored
Dec 11, 2019
by
konghaorui
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
补充私聊模块Api
parent
ffa78235
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
301 additions
and
15 deletions
+301
-15
FragmentContainerActivity.kt
app/src/main/java/com/ydl/component/music/FragmentContainerActivity.kt
+4
-0
config.gradle
config.gradle
+4
-2
modular.gradle
m-im/modular.gradle
+2
-3
P2PCustomActionHandlerImpl.java
m-im/src/main/java/com/yidianling/im/bridge/P2PCustomActionHandlerImpl.java
+2
-3
TeamRemoveEvent.kt
m-im/src/main/java/com/yidianling/im/event/TeamRemoveEvent.kt
+1
-1
ImObserversHelper.kt
m-im/src/main/java/com/yidianling/im/helper/ImObserversHelper.kt
+1
-1
IMServiceImpl.kt
m-im/src/main/java/com/yidianling/im/modular/service/IMServiceImpl.kt
+196
-0
IMRouterImp.kt
m-im/src/main/java/com/yidianling/im/router/IMRouterImp.kt
+2
-3
ImIn.kt
m-im/src/main/java/com/yidianling/im/router/ImIn.kt
+5
-0
IMLoginInfo.kt
m-im/src/main/modular_api/com/yidianling/im/api/bean/IMLoginInfo.kt
+10
-0
IMRequestCallback.kt
m-im/src/main/modular_api/com/yidianling/im/api/bean/IMRequestCallback.kt
+18
-0
SelectTabIMEvent.kt
m-im/src/main/modular_api/com/yidianling/im/api/event/SelectTabIMEvent.kt
+1
-1
IImService.kt
m-im/src/main/modular_api/com/yidianling/im/api/service/IImService.kt
+53
-0
colors.xml
m-im/src/main/res/values/colors.xml
+2
-1
No files found.
app/src/main/java/com/ydl/component/music/FragmentContainerActivity.kt
View file @
e9424c46
...
...
@@ -5,6 +5,7 @@ import android.content.Intent
import
android.support.v4.app.Fragment
import
com.ydl.component.mvp.DemoContract
import
com.ydl.component.mvp.DemoPresenter
import
com.ydl.ydlcommon.bean.StatusBarOptions
import
com.ydl.ydlcommon.mvp.lce.BaseLceActivity
import
com.yidianling.im.ui.page.NewMultiMessageFragment
...
...
@@ -19,6 +20,9 @@ class FragmentContainerActivity : BaseLceActivity<DemoContract.View, DemoContra
}
}
override
fun
getStatusViewOptions
():
StatusBarOptions
{
return
StatusBarOptions
(
isAddStatusView
=
true
,
statusBarDarkMode
=
true
)
}
override
fun
getContentViewId
():
Int
{
return
com
.
ydl
.
component
.
R
.
id
.
lce_content_view
...
...
config.gradle
View file @
e9424c46
...
...
@@ -52,7 +52,7 @@ ext {
"m-muse"
:
"0.0.19.5"
,
"m-tests"
:
"0.0.13.5"
,
"m-course"
:
"0.0.32"
,
"m-im"
:
"0.0.1"
,
//-------------- 业务模块 API 层 --------------
"m-audioim-api"
:
"0.0.5"
,
...
...
@@ -64,6 +64,7 @@ ext {
"m-tests-api"
:
"0.0.1"
,
"m-user-api"
:
"0.0.7"
,
"m-home-api"
:
"0.0.2"
,
"m-im-api"
:
"0.0.1"
,
//-------------- 功能组件 --------------
//第一步
...
...
@@ -89,9 +90,9 @@ ext {
"m-consultant"
:
"0.0.26"
,
"m-course"
:
"0.0.22"
,
"m-fm"
:
"0.0.15"
,
"m-tests"
:
"0.0.4"
,
"m-user"
:
"0.0.25"
,
"m-home"
:
"0.0.3"
,
"m-im"
:
"0.0.1"
,
// 以下为接入flutter的模块
"m-muse"
:
"0.0.7"
,
...
...
@@ -106,6 +107,7 @@ ext {
"m-tests-api"
:
"0.0.1"
,
"m-user-api"
:
"0.0.7"
,
"m-home-api"
:
"0.0.2"
,
"m-im-api"
:
"0.0.1"
,
//-------------- 功能组件 --------------
//第一步
...
...
m-im/modular.gradle
View file @
e9424c46
...
...
@@ -8,14 +8,14 @@ modular {
groupId
=
"com.ydl"
artifactId
=
"m-im-module-xlzx"
// 上报的 心理咨询 业务模块 aar 包的版本号
//
version = rootProject.ext.ydlPublishVersion[childProject.getName()]
version
=
rootProject
.
ext
.
ydlPublishVersion
[
childProject
.
getName
()]
}
ydl
{
groupId
=
"com.ydl"
artifactId
=
"m-im-module-ydl"
// 上报的 壹点灵 业务模块 aar 包的版本号
//
version = rootProject.ext.ydlPublishVersion[childProject.getName()]
version
=
rootProject
.
ext
.
ydlPublishVersion
[
childProject
.
getName
()]
}
}
...
...
@@ -30,7 +30,6 @@ modular {
implementation
"com.google.code.gson:gson:2.8.2"
implementation
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation
'com.alibaba:arouter-api:1.4.1'
implementation
'de.greenrobot:eventbus:2.4.0'
}
}
}
...
...
m-im/src/main/java/com/yidianling/im/bridge/P2PCustomActionHandlerImpl.java
View file @
e9424c46
...
...
@@ -42,6 +42,7 @@ import com.ydl.ydlcommon.view.dialog.CommonDialog;
import
com.ydl.ydlcommon.view.dialog.ListDialog
;
import
com.ydl.ydlcommon.view.dialog.NormalDialog
;
import
com.yidianling.common.tools.ToastUtil
;
import
com.yidianling.im.api.bean.IMRequestCallback
;
import
com.yidianling.im.api.event.BlackEvent
;
import
com.yidianling.im.bean.GetReportReason
;
import
com.yidianling.im.bean.RMBlackCall
;
...
...
@@ -61,9 +62,7 @@ import com.yidianling.im.session.extension.CustomAttachmentPhoneCallSystemNotice
import
com.yidianling.im.session.extension.CustomRecommendExpertListMsg
;
import
com.yidianling.im.session.extension.CustomSystemTips
;
import
com.yidianling.im.ui.widget.ChatTeamHisDialog
;
import
com.yidianling.router.RouterManager
;
import
com.yidianling.router.im.IMExpertBuild
;
import
com.yidianling.router.im.IMRequestCallback
;
import
com.yidianling.uikit.business.session.helper.MessageListPanelHelper
;
import
com.yidianling.uikit.custom.bridge.IP2PCustomActionHandler
;
import
com.yidianling.uikit.custom.http.response.RecommendExpertBean
;
...
...
@@ -193,7 +192,7 @@ public class P2PCustomActionHandlerImpl implements IP2PCustomActionHandler {
CustomMessageConfig
config
=
new
CustomMessageConfig
();
config
.
enableUnreadCount
=
false
;
message
.
setConfig
(
config
);
RouterManager
.
INSTANCE
.
getImRouter
().
createTextMessage
(
sessionId
,
"您好,请尽快上线,我在等您"
,
new
IMRequestCallback
<
Void
>()
{
ImIn
.
INSTANCE
.
getImService
().
createTextMessage
(
sessionId
,
"您好,请尽快上线,我在等您"
,
new
IMRequestCallback
<
Void
>()
{
@Override
public
void
onSuccess
(
@Nullable
Void
aVoid
)
{
}
...
...
m-im/src/main/
modular_api/com/yidianling/im/api
/event/TeamRemoveEvent.kt
→
m-im/src/main/
java/com/yidianling/im
/event/TeamRemoveEvent.kt
View file @
e9424c46
package
com.yidianling.im.
api.
event
package
com.yidianling.im.event
/**
* 群聊被踢出事件
...
...
m-im/src/main/java/com/yidianling/im/helper/ImObserversHelper.kt
View file @
e9424c46
...
...
@@ -17,7 +17,7 @@ import com.netease.nimlib.sdk.msg.model.RevokeMsgNotification
import
com.netease.nimlib.sdk.team.TeamServiceObserver
import
com.netease.nimlib.sdk.team.model.Team
import
com.yidianling.im.api.event.AccountChangeEvent
import
com.yidianling.im.
api.
event.TeamRemoveEvent
import
com.yidianling.im.event.TeamRemoveEvent
import
com.yidianling.im.preference.IMCache
import
com.yidianling.im.preference.ImTempData
import
com.yidianling.im.session.extension.CustomAttachReceivedMoney
...
...
m-im/src/main/java/com/yidianling/im/modular/service/IMServiceImpl.kt
0 → 100644
View file @
e9424c46
package
com.yidianling.im.modular.service
import
android.app.Activity
import
android.content.Context
import
android.support.v7.app.AppCompatActivity
import
com.alibaba.android.arouter.facade.annotation.Route
import
com.netease.nimlib.sdk.NIMClient
import
com.netease.nimlib.sdk.RequestCallback
import
com.netease.nimlib.sdk.auth.AuthService
import
com.netease.nimlib.sdk.auth.LoginInfo
import
com.netease.nimlib.sdk.msg.MessageBuilder
import
com.netease.nimlib.sdk.msg.MsgService
import
com.netease.nimlib.sdk.msg.constant.SessionTypeEnum
import
com.ydl.ydlcommon.router.YdlCommonOut
import
com.ydl.ydlcommon.utils.StringUtils
import
com.yidianling.im.R
import
com.yidianling.im.api.bean.IMLoginInfo
import
com.yidianling.im.api.bean.IMRequestCallback
import
com.yidianling.im.api.service.IImService
import
com.yidianling.im.bridge.P2PCustomActionHandlerImpl
import
com.yidianling.im.helper.IMUtil
import
com.yidianling.im.preference.IMCache
import
com.yidianling.im.router.ImIn
import
com.yidianling.im.session.SessionHelper
import
com.yidianling.im.session.extension.CustomAttachSubScriptTime
import
com.yidianling.im.session.extension.CustomAttachmentTest
import
com.yidianling.nimbase.common.media.picker.PickImageHelper
import
com.yidianling.uikit.api.NimUIKit
import
com.yidianling.uikit.business.session.helper.MessageListPanelHelper
/**
* Created by haorui on 2019-12-11 .
* Des:
*/
@Route
(
path
=
"/im/ImService"
)
class
IMServiceImpl
:
IImService
{
override
fun
init
(
context
:
Context
?)
{
}
override
fun
startP2PSession
(
context
:
Activity
,
toUid
:
String
)
{
IMUtil
.
startChat
(
context
as
AppCompatActivity
,
toUid
,
IMUtil
.
FLAG_SAVE
or
IMUtil
.
FLAG_USE_UM
,
0
,
null
)
}
override
fun
startP2PXiaoYi
(
context
:
Context
)
{
if
(!
ImIn
.
isLogin
())
{
context
.
startActivity
(
ImIn
.
loginWayIntent
(
context
))
return
}
SessionHelper
.
startP2PSession
(
context
,
-
1
,
"14"
,
null
,
P2PCustomActionHandlerImpl
(
"14"
,
"客服小壹"
,
"https://static.ydlcdn.com/mobile/images/avatar_girl_app.png"
))
}
override
fun
imLogin
(
info
:
IMLoginInfo
)
{
NimUIKit
.
setAccount
(
info
.
account
)
try
{
NIMClient
.
getService
(
AuthService
::
class
.
java
).
login
(
LoginInfo
(
info
.
account
,
info
.
passWord
))
}
catch
(
e
:
Exception
)
{
e
.
printStackTrace
()
}
}
override
fun
login
(
info
:
IMLoginInfo
,
callback
:
IMRequestCallback
<
IMLoginInfo
>?)
{
NimUIKit
.
login
(
LoginInfo
(
info
.
account
,
info
.
passWord
),
object
:
RequestCallback
<
LoginInfo
>
{
override
fun
onSuccess
(
param
:
LoginInfo
?)
{
if
(
param
!=
null
)
{
val
newParam
=
IMLoginInfo
(
param
.
account
,
param
.
token
)
callback
?.
onSuccess
(
newParam
)
}
}
override
fun
onFailed
(
code
:
Int
)
{
callback
?.
onFailed
(
code
)
}
override
fun
onException
(
exception
:
Throwable
?)
{
callback
?.
onException
(
exception
)
}
})
}
override
fun
setAccount
(
account
:
String
)
{
NimUIKit
.
setAccount
(
account
)
}
override
fun
setChattingAccountAll
()
{
NIMClient
.
getService
(
MsgService
::
class
.
java
).
setChattingAccount
(
MsgService
.
MSG_CHATTING_ACCOUNT_ALL
,
SessionTypeEnum
.
None
)
}
override
fun
setChattingAccountNone
()
{
NIMClient
.
getService
(
MsgService
::
class
.
java
).
setChattingAccount
(
MsgService
.
MSG_CHATTING_ACCOUNT_NONE
,
SessionTypeEnum
.
None
)
}
override
fun
logout
()
{
NIMClient
.
getService
(
AuthService
::
class
.
java
).
logout
()
}
override
fun
clear
()
{
NimUIKit
.
logout
()
IMCache
.
clear
()
}
override
fun
createTextMessage
(
sessionId
:
String
?,
content
:
String
,
callback
:
IMRequestCallback
<
Void
>)
{
val
message
=
MessageBuilder
.
createTextMessage
(
sessionId
,
SessionTypeEnum
.
P2P
,
content
)
NIMClient
.
getService
(
MsgService
::
class
.
java
)
.
sendMessage
(
message
,
false
)
.
setCallback
(
object
:
RequestCallback
<
Void
>
{
override
fun
onSuccess
(
param
:
Void
?)
{
callback
.
onSuccess
(
param
)
MessageListPanelHelper
.
getInstance
().
notifyAddMessage
(
message
)
}
override
fun
onException
(
exception
:
Throwable
?)
{
callback
.
onException
(
exception
)
}
override
fun
onFailed
(
code
:
Int
)
{
callback
.
onFailed
(
code
)
}
})
}
override
fun
sendSubscriptionTimeMessage
(
sessionId
:
String
?,
content
:
String
,
callback
:
IMRequestCallback
<
Void
>)
{
val
customTime
=
CustomAttachSubScriptTime
(
content
)
val
message
=
MessageBuilder
.
createCustomMessage
(
sessionId
,
SessionTypeEnum
.
P2P
,
content
,
customTime
)
NIMClient
.
getService
(
MsgService
::
class
.
java
)
.
sendMessage
(
message
,
false
)
.
setCallback
(
object
:
RequestCallback
<
Void
>
{
override
fun
onSuccess
(
param
:
Void
?)
{
callback
.
onSuccess
(
param
)
MessageListPanelHelper
.
getInstance
().
notifyAddMessage
(
message
)
}
override
fun
onException
(
exception
:
Throwable
?)
{
callback
.
onException
(
exception
)
}
override
fun
onFailed
(
code
:
Int
)
{
callback
.
onFailed
(
code
)
}
})
}
override
fun
showSelector
(
activity
:
Activity
,
requestCode
:
Int
)
{
val
option
=
PickImageHelper
.
PickImageOption
()
option
.
titleResId
=
R
.
string
.
input_panel_photo
option
.
multiSelect
=
true
option
.
multiSelectMaxCount
=
9
option
.
crop
=
false
option
.
cropOutputImageWidth
=
720
option
.
cropOutputImageHeight
=
720
// option.outputPath = StorageUtil.getWritePath(StringUtils.get32UUID() + ".jpg", StorageType.TYPE_TEMP)
option
.
outputPath
=
YdlCommonOut
.
getApp
().
externalCacheDir
.
absolutePath
+
"/"
+
StringUtils
.
get32UUID
()
+
".jpg"
PickImageHelper
.
pickImage
(
activity
,
requestCode
,
option
)
}
override
fun
sendTestResultMessage
(
uid
:
String
,
content
:
String
,
title
:
String
?,
head
:
String
?,
url
:
String
?,
id
:
Int
,
share_url
:
String
?,
callback
:
IMRequestCallback
<
Void
>)
{
val
customAttachmentTest
=
CustomAttachmentTest
(
CustomAttachmentTest
.
FLAG_RESULT
,
title
,
head
,
url
,
id
,
share_url
)
val
message
=
MessageBuilder
.
createCustomMessage
(
uid
,
SessionTypeEnum
.
P2P
,
"测试结果"
,
customAttachmentTest
)
NIMClient
.
getService
(
MsgService
::
class
.
java
).
sendMessage
(
message
,
false
).
setCallback
(
object
:
RequestCallback
<
Void
>
{
override
fun
onSuccess
(
param
:
Void
?)
{
callback
.
onSuccess
(
param
)
MessageListPanelHelper
.
getInstance
().
notifyAddMessage
(
message
)
}
override
fun
onFailed
(
code
:
Int
)
{
callback
.
onFailed
(
code
)
}
override
fun
onException
(
exception
:
Throwable
?)
{
callback
.
onException
(
exception
)
}
})
}
/**
* 跳转私聊界面
*/
override
fun
startChat
(
context
:
Activity
,
toUid
:
String
,
flag
:
Int
,
canTalk
:
Int
)
{
//这里虽然是倾述流程进入私聊,但不需要发送自定义消息
IMUtil
.
startChat
(
context
as
AppCompatActivity
,
toUid
,
0
x001
,
canTalk
,
null
,
0
,
false
)
}
}
\ No newline at end of file
m-im/src/main/java/com/yidianling/im/router/IMRouterImp.kt
View file @
e9424c46
...
...
@@ -10,6 +10,8 @@ import com.netease.nimlib.sdk.auth.LoginInfo
import
com.netease.nimlib.sdk.msg.MessageBuilder
import
com.netease.nimlib.sdk.msg.MsgService
import
com.netease.nimlib.sdk.msg.constant.SessionTypeEnum
import
com.ydl.ydlcommon.router.YdlCommonOut
import
com.ydl.ydlcommon.utils.StringUtils
import
com.yidianling.im.R
import
com.yidianling.im.bridge.P2PCustomActionHandlerImpl
import
com.yidianling.im.helper.IMUtil
...
...
@@ -19,13 +21,10 @@ import com.yidianling.im.session.extension.CustomAttachSubScriptTime
import
com.yidianling.im.session.extension.CustomAttachmentTest
import
com.yidianling.nimbase.common.media.picker.PickImageHelper
import
com.yidianling.router.im.IIMRouter
import
com.yidianling.router.im.IMExpertBuild
import
com.yidianling.router.im.IMLoginInfo
import
com.yidianling.router.im.IMRequestCallback
import
com.yidianling.uikit.api.NimUIKit
import
com.yidianling.uikit.business.session.helper.MessageListPanelHelper
import
com.ydl.ydlcommon.router.YdlCommonOut
import
com.ydl.ydlcommon.utils.StringUtils
/**
* author : Zhangwenchao
...
...
m-im/src/main/java/com/yidianling/im/router/ImIn.kt
View file @
e9424c46
...
...
@@ -17,6 +17,7 @@ import com.ydl.ydlcommon.data.PlatformDataManager
import
com.ydl.ydlcommon.modular.ModularServiceManager
import
com.ydl.ydlcommon.router.IYDLRouterConstant
import
com.yidianling.im.config.constants.UserPreferences
import
com.yidianling.im.modular.service.IMServiceImpl
import
com.yidianling.im.preference.IMCache
import
com.yidianling.router.RouterManager
import
com.yidianling.router.app.ReceiveRedPacketParam
...
...
@@ -31,6 +32,10 @@ import com.yidianling.user.api.service.IUserService
*/
object
ImIn
{
fun
getImService
():
IMServiceImpl
{
return
ModularServiceManager
.
provide
(
IMServiceImpl
::
class
.
java
)
}
fun
getUserService
():
IUserService
{
return
ModularServiceManager
.
provide
(
IUserService
::
class
.
java
)
}
...
...
m-im/src/main/modular_api/com/yidianling/im/api/bean/IMLoginInfo.kt
0 → 100644
View file @
e9424c46
package
com.yidianling.im.api.bean
/**
* author : Zhangwenchao
* e-mail : zhangwch@yidianling.com
* time : 2018/03/23
* 登录 im 时传入的参数,对应 im 模块中的 IMLoginInfo
*/
data class
IMLoginInfo
(
val
account
:
String
,
val
passWord
:
String
)
\ No newline at end of file
m-im/src/main/modular_api/com/yidianling/im/api/bean/IMRequestCallback.kt
0 → 100644
View file @
e9424c46
package
com.yidianling.im.api.bean
/**
* author : Zhangwenchao
* e-mail : zhangwch@yidianling.com
* time : 2018/03/23
* 登录 im 时传入的接口,对应 im 模块中的 IMRequestCallback
*/
interface
IMRequestCallback
<
in
T
>
{
fun
onSuccess
(
t
:
T
?)
fun
onFailed
(
i
:
Int
)
fun
onException
(
throwable
:
Throwable
?)
}
\ No newline at end of file
m-im/src/main/modular_api/com/yidianling/im/api/event/SelectTabIMEvent.kt
View file @
e9424c46
...
...
@@ -2,6 +2,6 @@ package com.yidianling.im.api.event
/**
* Created by haorui on 2019-12-10.
* Des:
* Des:
选中Tab事件
*/
class
SelectTabIMEvent
(
var
tab
:
Int
)
m-im/src/main/modular_api/com/yidianling/im/api/service/IImService.kt
0 → 100644
View file @
e9424c46
package
com.yidianling.im.api.service
import
android.app.Activity
import
android.content.Context
import
com.alibaba.android.arouter.facade.template.IProvider
import
com.yidianling.im.api.bean.IMLoginInfo
import
com.yidianling.im.api.bean.IMRequestCallback
/**
* author : Zhangwenchao
* e-mail : zhangwch@yidianling.com
* time : 2018/04/13
*/
interface
IImService
:
IProvider
{
// 打开与小壹聊天界面
fun
startP2PXiaoYi
(
context
:
Context
)
// 打开私聊界面
fun
startP2PSession
(
context
:
Activity
,
toUid
:
String
)
fun
setAccount
(
account
:
String
)
fun
setChattingAccountAll
()
fun
setChattingAccountNone
()
fun
login
(
info
:
IMLoginInfo
,
callback
:
IMRequestCallback
<
IMLoginInfo
>?)
/**
* 绑定手机后,重新登录IM
*/
fun
imLogin
(
info
:
IMLoginInfo
)
fun
logout
()
fun
clear
()
/**
* 创建一条普通文本消息
* @param sessionId 聊天对象ID
* @param content 文本消息内容
*/
fun
createTextMessage
(
sessionId
:
String
?,
content
:
String
,
callback
:
IMRequestCallback
<
Void
>)
fun
sendSubscriptionTimeMessage
(
sessionId
:
String
?,
content
:
String
,
callback
:
IMRequestCallback
<
Void
>)
fun
showSelector
(
activity
:
Activity
,
requestCode
:
Int
)
fun
sendTestResultMessage
(
uid
:
String
,
content
:
String
,
title
:
String
?,
head
:
String
?,
url
:
String
?,
id
:
Int
,
share_url
:
String
?,
callback
:
IMRequestCallback
<
Void
>)
fun
startChat
(
context
:
Activity
,
toUid
:
String
,
flag
:
Int
,
canTalk
:
Int
)
}
\ No newline at end of file
m-im/src/main/res/values/colors.xml
View file @
e9424c46
...
...
@@ -83,6 +83,6 @@
<color
name=
"divide_color"
>
#EDEDED
</color>
<color
name=
"default_button_bg"
>
#1da1f2
</color>
<color
name=
"default_text_color"
>
#555555
</color>
<color
name=
"theme_title_bar_color"
>
#
2e2e31
</color>
<color
name=
"theme_title_bar_color"
>
#
FFFFFF
</color>
<color
name=
"color_grey_d0d0d0"
>
#d0d0d0
</color>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment