Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
pidan
/
FuSiLive
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
dcdea2da
authored
Mar 31, 2025
by
ludi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
完成直播重新认定以及新版本直播质量展示
parent
374fdda6
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
196 additions
and
18 deletions
DevelopmentPods/FUSCommon/FUSCommon/Classes/Common/Models/FUSLiveAssesDetailModel.h
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Model/FUSAssessQualityInfoModel.h
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Model/FUSAssessQualityInfoModel.m
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHttpHelper.h
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHttpHelper.m
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/FUSVideoEndView/FUSVideoEndLiveScoreSheetView.swift
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/FUSVideoEndView/FUSVideoEndScoreQualityAlertView.swift
Modules/FUSShowRoomModule/FUSShowRoomModule/Others/FUSShowRoomURLs.h
Modules/FUSShowRoomModule/FUSShowRoomModule/Others/FUSShowRoomURLs.m
Modules/FUSShowRoomModule/FUSShowRoomModule/Router/FUSShowRoomRouter.m
DevelopmentPods/FUSCommon/FUSCommon/Classes/Common/Models/FUSLiveAssesDetailModel.h
View file @
dcdea2da
...
...
@@ -15,10 +15,15 @@ NS_ASSUME_NONNULL_BEGIN
@property
(
nonatomic
,
assign
)
NSInteger
level
;
/// 得分
@property
(
nonatomic
,
assign
)
NSInteger
score
;
// MARK: 下面都是只有在quality直播质量里面才有的属性
/// 目标,直播质量有,是所有目标项
@property
(
nonatomic
,
assign
)
NSInteger
target
;
/// 序列ID,直播质量有
@property
(
nonatomic
,
strong
)
NSString
*
sid
;
/// 评级名称 只有直播质量有
@property
(
nonatomic
,
copy
)
NSString
*
levelName
;
#pragma mark - 额外的属性,为了其他模型定制的
/// 进度
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Model/FUSAssessQualityInfoModel.h
View file @
dcdea2da
...
...
@@ -9,6 +9,26 @@
NS_ASSUME_NONNULL_BEGIN
@class
FUSAssessQualityInfoModel
;
@interface
FUSAssessQualityInfoRequestModel
:
FUSBaseModel
/// 直播质量各项列表
@property
(
nonatomic
,
copy
)
NSArray
<
FUSAssessQualityInfoModel
*>
*
dataList
;
/// 结果状态(0:首次、1:非首次
@property
(
nonatomic
,
assign
)
NSInteger
resultCase
;
/// 结果提示文案
@property
(
nonatomic
,
copy
)
NSString
*
resultHint
;
/// 评级
@property
(
nonatomic
,
assign
)
NSInteger
resultLevel
;
/// 评级标题
@property
(
nonatomic
,
copy
)
NSString
*
resultLevelName
;
/// 获取评级显示的颜色
-
(
UIColor
*
)
fus_getLevelColor
;
@end
@interface
FUSAssessQualityInfoModel
:
FUSBaseModel
/// 选项ID
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Model/FUSAssessQualityInfoModel.m
View file @
dcdea2da
...
...
@@ -7,6 +7,23 @@
#import "FUSAssessQualityInfoModel.h"
@implementation
FUSAssessQualityInfoRequestModel
+
(
NSDictionary
*
)
modelContainerPropertyGenericClass
{
return
@{
@"dataList"
:
[
FUSAssessQualityInfoModel
class
]};
}
-
(
UIColor
*
)
fus_getLevelColor
{
NSArray
*
colors
=
@[[
UIColor
colorWithHex
:
@"#DFDEDE"
],
[
UIColor
colorWithHex
:
@"#FB2424"
],
[
UIColor
colorWithHex
:
@"#FC8226"
],
[
UIColor
colorWithHex
:
@"#00F088"
],
[
UIColor
colorWithHex
:
@"#0394FA"
]];
if
(
self
.
resultLevel
>=
0
&&
self
.
resultLevel
<=
4
)
{
return
colors
[
self
.
resultLevel
];;
}
return
[
UIColor
colorWithHex
:
@"#DFDEDE"
];
}
@end
@implementation
FUSAssessQualityInfoModel
@end
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHttpHelper.h
View file @
dcdea2da
...
...
@@ -934,11 +934,21 @@ NS_ASSUME_NONNULL_BEGIN
/// 获取用户直播质量详细
/// @param sid id
/// @param type 类型(1:房间)
/// @param succeed 1
/// @param failure 0
+
(
void
)
fus_requestUserliveAssessQualityInfoWithSid
:(
NSString
*
)
sid
succeed
:(
void
(
^
)(
NSArray
<
FUSAssessQualityInfoModel
*>
*
modelList
))
succeed
type
:(
NSInteger
)
type
succeed
:(
void
(
^
)(
FUSAssessQualityInfoRequestModel
*
model
))
succeed
failure
:(
void
(
^
)(
NSString
*
msg
,
NSInteger
code
))
failure
;
/// 重申直播质量认定
/// @param sid SID
/// @param succeed 1
/// @param failure 0
+
(
void
)
fus_requestUserliveAssessQualityReaffirmWithSid
:(
NSString
*
)
sid
succeed
:(
void
(
^
)(
void
))
succeed
failure
:(
void
(
^
)(
NSString
*
msg
,
NSInteger
code
))
failure
;
/// 结束直播
/// @param roomId 房间id
/// @param channelId 直播场次ID
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/Other/FUSLiveHttpHelper.m
View file @
dcdea2da
...
...
@@ -2515,14 +2515,25 @@
}];
}
/// 获取用户直播质量详细
+
(
void
)
fus_requestUserliveAssessQualityInfoWithSid
:
(
NSString
*
)
sid
succeed
:
(
void
(
^
)(
NSArray
<
FUSAssessQualityInfoModel
*>
*
))
succeed
failure
:
(
void
(
^
)(
NSString
*
,
NSInteger
))
failure
{
NSDictionary
*
parm
=
@{
@"sid"
:
sid
};
+
(
void
)
fus_requestUserliveAssessQualityInfoWithSid
:
(
NSString
*
)
sid
type
:
(
NSInteger
)
type
succeed
:
(
void
(
^
)(
FUSAssessQualityInfoRequestModel
*
_Nonnull
))
succeed
failure
:
(
void
(
^
)(
NSString
*
_Nonnull
,
NSInteger
))
failure
{
NSDictionary
*
parm
=
@{
@"sid"
:
sid
,
@"type"
:
@
(
type
)};
[
FUSHttpHelper
postRequestBinaryWithUrl
:
FUSShowRoomURLs
.
fus_URL_userliveAssessQualityInfo
params
:
parm
success
:^
(
NSDictionary
*
_Nullable
dataDict
,
int
code
)
{
succeed
([
NSArray
modelArrayWithClass
:[
FUSAssessQualityInfoModel
class
]
json
:
dataDict
[
@"dataList"
]]);
succeed
([
FUSAssessQualityInfoRequestModel
fus_modelWithDict
:
dataDict
]);
}
failure
:^
(
NSDictionary
*
_Nullable
dataDict
,
int
code
)
{
if
(
failure
)
failure
(
dataDict
[
@"msg"
],
code
);
}];
}
/// 重申直播质量认定
+
(
void
)
fus_requestUserliveAssessQualityReaffirmWithSid
:
(
NSString
*
)
sid
succeed
:
(
void
(
^
)(
void
))
succeed
failure
:
(
void
(
^
)(
NSString
*
_Nonnull
,
NSInteger
))
failure
{
NSDictionary
*
parm
=
@{
@"sid"
:
sid
};
[
FUSHttpHelper
postRequestBinaryWithUrl
:
FUSShowRoomURLs
.
fus_URL_userliveAssessQualityReaffirm
params
:
parm
success
:^
(
NSDictionary
*
_Nullable
dataDict
,
int
code
)
{
succeed
();
}
failure
:^
(
NSDictionary
*
_Nullable
dataDict
,
int
code
)
{
if
(
failure
)
failure
(
dataDict
[
@"msg"
],
code
);
}];
}
/// 结束直播
+
(
void
)
fus_requestEndLiveWithRoomId
:
(
NSString
*
)
roomid
channelId
:
(
NSString
*
)
channelId
succeed
:
(
void
(
^
)(
NSDictionary
*
))
succeed
failure
:
(
void
(
^
)(
NSString
*
,
NSInteger
))
failure
{
NSDictionary
*
parm
=
@{
@"roomid"
:
roomid
,
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/FUSVideoEndView/FUSVideoEndLiveScoreSheetView.swift
View file @
dcdea2da
...
...
@@ -201,10 +201,10 @@ extension FUSVideoEndLiveScoreSheetView {
if
type
==
.
quality
{
FUSLoadingView
.
fus_showProgressView
(
withMessage
:
""
,
canTouchBottomView
:
false
)
FUSLiveHttpHelper
.
fus_requestUserliveAssessQualityInfo
(
withSid
:
self
.
liveAssessModel
.
quality
.
sid
)
{[
weak
self
]
dataList
in
FUSLiveHttpHelper
.
fus_requestUserliveAssessQualityInfo
(
withSid
:
self
.
liveAssessModel
.
quality
.
sid
,
type
:
0
)
{[
weak
self
]
model
in
FUSLoadingView
.
fus_dismissProgressView
()
guard
let
self
=
self
else
{
return
}
FUSVideoEndScoreQualityAlertView
.
fus_create
(
dataList
:
dataList
,
showOn
:
self
)
FUSVideoEndScoreQualityAlertView
.
fus_create
(
model
:
model
,
showOn
:
self
)
}
failure
:
{
msg
,
code
in
FUSLoadingView
.
fus_dismissProgressView
()
FUSDialogView
.
fus_showDialog
(
msg
)
...
...
@@ -360,8 +360,11 @@ class FFVideoEndLiveScoreBlankButton: UIButton {
make
.
append
(
""
)
make
.
append
(
"
\(
model
.
score
)
"
)
.
textColor
(
UIColor
.
fus_fireGreen
())
case
.
quality
:
make
.
append
(
"
\(
model
.
levelName
)
"
)
.
textColor
(
model
.
fus_color
)
make
.
append
(
"("
)
make
.
append
(
"
\(
model
.
score
)
"
)
.
textColor
(
model
.
fus_color
)
make
.
append
(
"/
\(
model
.
target
)
"
)
.
textColor
(
.
init
(
hex
:
"#111111"
))
make
.
append
(
"/
\(
model
.
target
)
)"
)
make
.
textColor
(
.
init
(
hex
:
"#111111"
))
}
make
.
font
(
UIFont
.
fus_themeFont
(
18
))
})
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Features/NewLive/Main/View/FUSVideoEndView/FUSVideoEndScoreQualityAlertView.swift
View file @
dcdea2da
...
...
@@ -10,28 +10,69 @@ import RxSwift
@objcMembers
public
class
FUSVideoEndScoreQualityAlertView
:
FUSBaseView
{
@objc
static
public
func
fus_create
(
dataList
:
[
FUSAssessQualityInfoModel
],
showOn
:
UIView
?
=
nil
)
{
@objc
public
enum
FUSVideoEndScoreQualityAlertClickedType
:
Int
{
/// 普通关闭
case
close
/// 重新认证
case
reidentify
}
@objc
static
public
func
fus_create
(
model
:
FUSAssessQualityInfoRequestModel
,
showOn
:
UIView
?
=
nil
)
{
guard
let
showOnView
=
((
showOn
!=
nil
)
?
showOn
:
UIViewController
.
fus_top
()?
.
view
)
else
{
return
}
let
view
=
FUSVideoEndScoreQualityAlertView
(
frame
:
showOnView
.
bounds
)
view
.
dataModel
=
model
showOnView
.
addSubview
(
view
)
view
.
fus_showWithAnimation
()
}
/// 创建一个有重新认定的质量认定弹窗
@objc
static
public
func
fus_createWithReidentify
(
model
:
FUSAssessQualityInfoRequestModel
,
showOn
:
UIView
?
=
nil
,
clickedHandler
:((
FUSVideoEndScoreQualityAlertClickedType
)
->
Void
)?)
{
guard
let
showOnView
=
((
showOn
!=
nil
)
?
showOn
:
UIViewController
.
fus_top
()?
.
view
)
else
{
return
}
let
view
=
FUSVideoEndScoreQualityAlertView
(
frame
:
showOnView
.
bounds
)
view
.
dataList
=
dataList
view
.
dataModel
=
model
view
.
reidentify
=
true
view
.
clickedHandler
=
clickedHandler
showOnView
.
addSubview
(
view
)
view
.
fus_showWithAnimation
()
}
var
data
List
:
[
FUSAssessQualityInfoModel
]
=
.
init
()
{
var
data
Model
:
FUSAssessQualityInfoRequestModel
=
.
init
()
{
didSet
{
self
.
fus_reloadData
()
}
}
/// 点击回调
var
clickedHandler
:((
FUSVideoEndScoreQualityAlertClickedType
)
->
Void
)?
/// 重新认定的提示,如果为空,则不显示重新认定的标志
var
reidentify
:
Bool
=
false
{
didSet
{
if
reidentify
==
true
{
self
.
reidentifyBtn
.
isHidden
=
false
self
.
okBtn
.
snp
.
updateConstraints
{
make
in
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
44
)
}
}
else
{
self
.
reidentifyBtn
.
isHidden
=
true
self
.
okBtn
.
snp
.
updateConstraints
{
make
in
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
32
)
}
}
}
}
let
bgBtn
=
UIButton
(
type
:
.
custom
)
let
contentView
=
UIImageView
(
frame
:
CGRectMake
(
0
,
0
,
UIView
.
fus_screenW
(),
300
))
let
titleLabel
=
UILabel
()
let
qualityGradeLabel
=
UILabel
()
let
qualityInfoBgView
=
UIView
()
var
qualityInfoViewList
:
[
FFScoreQualityItemView
]
=
.
init
()
let
okBtn
=
FUSStyleButton
(
type
:
.
custom
)
let
reidentifyBtn
=
UIButton
(
type
:
.
custom
)
public
override
func
makeUI
()
{
self
.
alpha
=
0
...
...
@@ -61,10 +102,16 @@ import RxSwift
make
.
centerX
.
equalToSuperview
()
}
contentView
.
addSubview
(
qualityGradeLabel
)
qualityGradeLabel
.
snp
.
makeConstraints
{
make
in
make
.
top
.
equalTo
(
titleLabel
.
snp
.
bottom
)
.
offset
(
16
)
make
.
centerX
.
equalToSuperview
()
}
contentView
.
addSubview
(
qualityInfoBgView
)
qualityInfoBgView
.
snp
.
makeConstraints
{
make
in
make
.
left
.
right
.
equalToSuperview
()
.
inset
(
22
)
make
.
top
.
equalTo
(
titl
eLabel
.
snp
.
bottom
)
.
offset
(
10
)
make
.
top
.
equalTo
(
qualityGrad
eLabel
.
snp
.
bottom
)
.
offset
(
10
)
}
okBtn
.
style
=
.
blue
...
...
@@ -77,22 +124,48 @@ import RxSwift
make
.
size
.
equalTo
(
CGSizeMake
(
214
,
42
))
make
.
bottom
.
equalToSuperview
()
.
offset
(
-
32
)
}
reidentifyBtn
.
isHidden
=
true
reidentifyBtn
.
setAttributedTitle
(
.
sj
.
makeText
({
make
in
make
.
append
(
.
fus_localString
(
"申请重新认定"
))
.
textColor
(
.
fus_textColorLight
())
.
underLine
{
make
in
make
.
style
=
.
single
make
.
color
=
.
fus_textColorLight
()
}
make
.
font
(
.
fus_themeFont
(
11
))
}),
for
:
.
normal
)
contentView
.
addSubview
(
reidentifyBtn
)
reidentifyBtn
.
snp
.
makeConstraints
{
make
in
make
.
centerX
.
equalToSuperview
()
make
.
top
.
equalTo
(
okBtn
.
snp
.
bottom
)
.
offset
(
9
)
}
}
public
override
func
bindViewModel
()
{
okBtn
.
rx
.
tap
.
subscribe
(
onNext
:
{[
weak
self
]
in
self
?
.
fus_dismissWithAnimation
()
self
?
.
clickedHandler
?(
.
close
)
})
.
disposed
(
by
:
disposeBag
)
reidentifyBtn
.
rx
.
tap
.
subscribe
(
onNext
:
{[
weak
self
]
in
self
?
.
fus_dismissWithAnimation
()
self
?
.
clickedHandler
?(
.
reidentify
)
})
.
disposed
(
by
:
disposeBag
)
}
func
fus_reloadData
(){
self
.
qualityGradeLabel
.
attributedText
=
.
sj
.
makeText
({
make
in
make
.
append
(
.
fus_versionLocalString
(
"質量評級"
)
+
":"
)
.
textColor
(
.
fus_textColorRich
())
make
.
append
(
self
.
dataModel
.
resultLevelName
)
.
textColor
(
self
.
dataModel
.
fus_getLevelColor
())
.
font
(
.
fus_themeMediumFont
(
20
))
make
.
font
(
.
fus_themeFont
(
15
))
})
self
.
qualityInfoViewList
.
removeAll
()
self
.
qualityInfoBgView
.
removeAllSubviews
()
var
qualityTopConstrain
=
self
.
qualityInfoBgView
.
snp
.
top
for
(
index
,
model
)
in
self
.
dataList
.
enumerated
()
{
for
(
index
,
model
)
in
self
.
data
Model
.
data
List
.
enumerated
()
{
let
qualityView
=
FFScoreQualityItemView
(
frame
:
.
zero
)
qualityView
.
model
=
model
...
...
@@ -101,13 +174,13 @@ import RxSwift
qualityView
.
snp
.
makeConstraints
{
make
in
make
.
left
.
right
.
equalToSuperview
()
make
.
top
.
equalTo
(
qualityTopConstrain
)
.
offset
(
10
)
if
index
==
self
.
dataList
.
count
-
1
{
if
index
==
self
.
data
Model
.
data
List
.
count
-
1
{
make
.
bottom
.
equalToSuperview
()
}
}
qualityTopConstrain
=
qualityView
.
snp
.
bottom
qualityView
.
lineView
.
isHidden
=
index
==
self
.
dataList
.
count
-
1
qualityView
.
lineView
.
isHidden
=
index
==
self
.
data
Model
.
data
List
.
count
-
1
self
.
qualityInfoViewList
.
append
(
qualityView
)
}
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Others/FUSShowRoomURLs.h
View file @
dcdea2da
...
...
@@ -418,6 +418,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 获取用户直播质量详细
+
(
NSString
*
)
fus_URL_userliveAssessQualityInfo
;
/// 重申直播质量认定
+
(
NSString
*
)
fus_URL_userliveAssessQualityReaffirm
;
/// 结束直播
+
(
NSString
*
)
fus_URL_liveEnd
;
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Others/FUSShowRoomURLs.m
View file @
dcdea2da
...
...
@@ -538,6 +538,10 @@
+
(
NSString
*
)
fus_URL_userliveAssessQualityInfo
{
return
[
FUSConfig
.
sharedInstanced
.
pathConfigs
apiUrl
:
@"/userlive/assess/quality/info"
];
}
/// 重申直播质量认定
+
(
NSString
*
)
fus_URL_userliveAssessQualityReaffirm
{
return
[
FUSConfig
.
sharedInstanced
.
pathConfigs
apiUrl
:
@"/userlive/assess/quality/reaffirm"
];
}
/// 结束直播
+
(
NSString
*
)
fus_URL_liveEnd
{
return
[
FUSConfig
.
sharedInstanced
.
pathConfigs
apiUrl
:
@"/live/end"
];
...
...
Modules/FUSShowRoomModule/FUSShowRoomModule/Router/FUSShowRoomRouter.m
View file @
dcdea2da
...
...
@@ -422,15 +422,47 @@
}
-
(
void
)
fus_showVideoScoreQualityAlertView
:
(
NSString
*
)
sid
{
[
FUSLiveHttpHelper
fus_requestUserliveAssessQualityInfoWithSid
:
sid
succeed
:
^
(
NSArray
<
FUSAssessQualityInfoModel
*>
*
_Nonnull
modelList
)
{
[
FUSVideoEndScoreQualityAlertView
fus_createWithDataList
:
modelList
showOn
:[
UIViewController
fus_topViewController
].
view
];
NSInteger
type
=
0
;
if
([
FUSLiveHelper
shareInstance
].
liveType
==
FUSLiveTypeAnchor
)
{
type
=
1
;
}
MJWeakSelf
[
FUSLiveHttpHelper
fus_requestUserliveAssessQualityInfoWithSid
:
sid
type
:
type
succeed
:^
(
FUSAssessQualityInfoRequestModel
*
_Nonnull
model
)
{
if
([
FUSLiveHelper
shareInstance
].
liveType
==
FUSLiveTypeAnchor
&&
model
.
resultCase
==
1
)
{
[
FUSVideoEndScoreQualityAlertView
fus_createWithReidentifyWithModel
:
model
showOn
:[
UIViewController
fus_topViewController
].
view
clickedHandler
:^
(
enum
FUSVideoEndScoreQualityAlertClickedType
clickType
)
{
if
(
clickType
==
FUSVideoEndScoreQualityAlertClickedTypeReidentify
)
{
// 申请重新认定
if
([
NSString
isNull
:
model
.
resultHint
])
{
// 没有提示直接确定
[
weakSelf
fus_userliveAssessQualityReaffirmHandlerWithSid
:
sid
];
}
else
{
// 有提示展示提示
[
FUSAlertView
showAlertWithTitle
:[
NSString
fus_localString
:
@"直播基础质量"
]
message
:
model
.
resultHint
cancelButtonTitle
:
[
NSString
fus_localString
:
@"取消"
]
otherButtonTitles
:
@[[
NSString
fus_localString
:
@"确认"
]]
clickBlock
:^
(
NSInteger
buttonIndex
)
{
if
(
clickType
==
1
)
{
[
weakSelf
fus_userliveAssessQualityReaffirmHandlerWithSid
:
sid
];
}
}];
}
}
}];
}
else
{
[
FUSVideoEndScoreQualityAlertView
fus_createWithModel
:
model
showOn
:[
UIViewController
fus_topViewController
].
view
];
}
}
failure
:^
(
NSString
*
_Nonnull
msg
,
NSInteger
code
)
{
}];
}
-
(
void
)
fus_userliveAssessQualityReaffirmHandlerWithSid
:
(
NSString
*
)
sid
{
[
FUSLiveHttpHelper
fus_requestUserliveAssessQualityReaffirmWithSid
:
sid
succeed
:
^
{
[
FUSDialogView
fus_showDialog
:[
NSString
fus_localString
:
@"申请重新认定成功"
]];
}
failure
:^
(
NSString
*
_Nonnull
msg
,
NSInteger
code
)
{
[
FUSDialogView
fus_showDialog
:
msg
];
}];
}
#pragma mark - HTTP
/**
* 追踪包房
...
...
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