Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
X
xabber-android
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
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
Administrator
xabber-android
Commits
8599d1dc
Commit
8599d1dc
authored
May 29, 2013
by
Alexander Ivanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move actions processing into chat viewer fragment.
parent
3ffd3912
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
188 additions
and
223 deletions
+188
-223
ChatViewer.java
src/com/xabber/android/ui/ChatViewer.java
+6
-183
ChatViewerFragment.java
src/com/xabber/android/ui/ChatViewerFragment.java
+178
-11
ChatViewerAdapter.java
src/com/xabber/android/ui/adapter/ChatViewerAdapter.java
+4
-0
OnTextChangedListener.java
src/com/xabber/android/ui/adapter/OnTextChangedListener.java
+0
-29
No files found.
src/com/xabber/android/ui/ChatViewer.java
View file @
8599d1dc
...
...
@@ -19,39 +19,23 @@ import java.util.Collection;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
android.text.ClipboardManager
;
import
android.view.ContextMenu
;
import
android.view.ContextMenu.ContextMenuInfo
;
import
android.view.KeyEvent
;
import
android.view.Menu
;
import
android.view.MenuItem
;
import
android.view.View
;
import
android.view.inputmethod.EditorInfo
;
import
android.view.inputmethod.InputMethodManager
;
import
android.widget.AdapterView.AdapterContextMenuInfo
;
import
android.widget.EditText
;
import
android.widget.ListView
;
import
android.widget.TextView
;
import
android.widget.TextView.OnEditorActionListener
;
import
com.xabber.android.data.ActivityManager
;
import
com.xabber.android.data.Application
;
import
com.xabber.android.data.LogManager
;
import
com.xabber.android.data.SettingsManager
;
import
com.xabber.android.data.SettingsManager.ChatsHideKeyboard
;
import
com.xabber.android.data.account.OnAccountChangedListener
;
import
com.xabber.android.data.entity.BaseEntity
;
import
com.xabber.android.data.extension.archive.MessageArchiveManager
;
import
com.xabber.android.data.extension.attention.AttentionManager
;
import
com.xabber.android.data.extension.cs.ChatStateManager
;
import
com.xabber.android.data.intent.EntityIntentBuilder
;
import
com.xabber.android.data.message.MessageItem
;
import
com.xabber.android.data.message.MessageManager
;
import
com.xabber.android.data.message.OnChatChangedListener
;
import
com.xabber.android.data.notification.NotificationManager
;
import
com.xabber.android.data.roster.OnContactChangedListener
;
import
com.xabber.android.ui.adapter.ChatViewerAdapter
;
import
com.xabber.android.ui.adapter.OnTextChangedListener
;
import
com.xabber.android.ui.helper.ManagedActivity
;
import
com.xabber.android.ui.widget.PageSwitcher
;
import
com.xabber.android.ui.widget.PageSwitcher.OnSelectListener
;
...
...
@@ -66,10 +50,9 @@ import com.xabber.androiddev.R;
* @author alexander.ivanov
*
*/
public
class
ChatViewer
extends
ManagedActivity
implements
View
.
OnClickListener
,
View
.
OnKeyListener
,
OnSelectListener
,
public
class
ChatViewer
extends
ManagedActivity
implements
OnSelectListener
,
OnChatChangedListener
,
OnContactChangedListener
,
OnAccountChangedListener
,
OnEditorActionListener
,
OnTextChangedListener
{
OnAccountChangedListener
{
/**
* Attention request.
...
...
@@ -91,8 +74,6 @@ public class ChatViewer extends ManagedActivity implements
private
boolean
isVisible
;
private
boolean
skipOnTextChanges
;
@Override
public
void
onCreate
(
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
...
...
@@ -154,7 +135,7 @@ public class ChatViewer extends ManagedActivity implements
intent
.
removeExtra
(
Intent
.
EXTRA_TEXT
);
exitOnSend
=
true
;
if
(
actionWithView
!=
null
)
insertText
(
additional
);
chatViewerAdapter
.
insertText
(
actionWithView
,
additional
);
}
}
isVisible
=
true
;
...
...
@@ -214,115 +195,6 @@ public class ChatViewer extends ManagedActivity implements
return
true
;
}
@Override
public
void
onCreateContextMenu
(
ContextMenu
menu
,
View
view
,
ContextMenuInfo
menuInfo
)
{
super
.
onCreateContextMenu
(
menu
,
view
,
menuInfo
);
AdapterContextMenuInfo
info
=
(
AdapterContextMenuInfo
)
menuInfo
;
pageSwitcher
.
stopMovement
();
ListView
listView
=
(
ListView
)
actionWithView
.
findViewById
(
android
.
R
.
id
.
list
);
final
MessageItem
message
=
(
MessageItem
)
listView
.
getAdapter
()
.
getItem
(
info
.
position
);
if
(
message
!=
null
&&
message
.
getAction
()
!=
null
)
return
;
if
(
message
.
isError
())
{
menu
.
add
(
R
.
string
.
message_repeat
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
sendMessage
(
message
.
getText
());
return
true
;
}
});
}
menu
.
add
(
R
.
string
.
message_quote
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
insertText
(
"> "
+
message
.
getText
()
+
"\n"
);
return
true
;
}
});
menu
.
add
(
R
.
string
.
message_copy
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
((
ClipboardManager
)
getSystemService
(
CLIPBOARD_SERVICE
))
.
setText
(
message
.
getSpannable
());
return
true
;
}
});
menu
.
add
(
R
.
string
.
message_remove
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
MessageManager
.
getInstance
().
removeMessage
(
message
);
chatViewerAdapter
.
onChatChange
(
actionWithView
,
false
);
return
true
;
}
});
}
/**
* Insert additional text to the input.
*
* @param additional
*/
private
void
insertText
(
String
additional
)
{
EditText
editView
=
(
EditText
)
actionWithView
.
findViewById
(
R
.
id
.
chat_input
);
String
source
=
editView
.
getText
().
toString
();
int
selection
=
editView
.
getSelectionEnd
();
if
(
selection
==
-
1
)
selection
=
source
.
length
();
else
if
(
selection
>
source
.
length
())
selection
=
source
.
length
();
String
before
=
source
.
substring
(
0
,
selection
);
String
after
=
source
.
substring
(
selection
);
if
(
before
.
length
()
>
0
&&
!
before
.
endsWith
(
"\n"
))
additional
=
"\n"
+
additional
;
editView
.
setText
(
before
+
additional
+
after
);
editView
.
setSelection
(
selection
+
additional
.
length
());
}
@Override
public
void
onClick
(
View
view
)
{
switch
(
view
.
getId
())
{
case
R
.
id
.
chat_send
:
sendMessage
();
break
;
case
R
.
id
.
title
:
ListView
listView
=
(
ListView
)
actionWithView
.
findViewById
(
android
.
R
.
id
.
list
);
int
size
=
listView
.
getCount
();
if
(
size
>
0
)
listView
.
setSelection
(
size
-
1
);
default
:
break
;
}
}
@Override
public
boolean
onKey
(
View
view
,
int
keyCode
,
KeyEvent
event
)
{
if
(
event
.
getAction
()
==
KeyEvent
.
ACTION_DOWN
&&
keyCode
==
KeyEvent
.
KEYCODE_ENTER
&&
SettingsManager
.
chatsSendByEnter
())
{
sendMessage
();
return
true
;
}
return
false
;
}
@Override
public
boolean
onKeyDown
(
int
keyCode
,
KeyEvent
event
)
{
switch
(
keyCode
)
{
...
...
@@ -342,12 +214,9 @@ public class ChatViewer extends ManagedActivity implements
}
}
@Override
public
void
onTextChanged
(
EditText
editText
,
CharSequence
text
)
{
if
(
skipOnTextChanges
)
return
;
ChatStateManager
.
getInstance
().
onComposing
(
actionWithAccount
,
actionWithUser
,
text
);
void
onSent
()
{
if
(
exitOnSend
)
close
();
}
@Override
...
...
@@ -382,43 +251,6 @@ public class ChatViewer extends ManagedActivity implements
LogManager
.
i
(
this
,
"onUnselect"
);
}
private
void
sendMessage
()
{
if
(
actionWithView
==
null
)
return
;
EditText
editView
=
(
EditText
)
actionWithView
.
findViewById
(
R
.
id
.
chat_input
);
String
text
=
editView
.
getText
().
toString
();
int
start
=
0
;
int
end
=
text
.
length
();
while
(
start
<
end
&&
(
text
.
charAt
(
start
)
==
' '
||
text
.
charAt
(
start
)
==
'\n'
))
start
+=
1
;
while
(
start
<
end
&&
(
text
.
charAt
(
end
-
1
)
==
' '
||
text
.
charAt
(
end
-
1
)
==
'\n'
))
end
-=
1
;
text
=
text
.
substring
(
start
,
end
);
if
(
""
.
equals
(
text
))
return
;
skipOnTextChanges
=
true
;
editView
.
setText
(
""
);
skipOnTextChanges
=
false
;
sendMessage
(
text
);
if
(
exitOnSend
)
close
();
if
(
SettingsManager
.
chatsHideKeyboard
()
==
ChatsHideKeyboard
.
always
||
(
getResources
().
getBoolean
(
R
.
bool
.
landscape
)
&&
SettingsManager
.
chatsHideKeyboard
()
==
ChatsHideKeyboard
.
landscape
))
{
InputMethodManager
imm
=
(
InputMethodManager
)
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
imm
.
hideSoftInputFromWindow
(
editView
.
getWindowToken
(),
0
);
}
}
private
void
sendMessage
(
String
text
)
{
MessageManager
.
getInstance
().
sendMessage
(
actionWithAccount
,
actionWithUser
,
text
);
chatViewerAdapter
.
onChatChange
(
actionWithView
,
false
);
}
@Override
public
void
onChatChanged
(
final
String
account
,
final
String
user
,
final
boolean
incoming
)
{
...
...
@@ -475,15 +307,6 @@ public class ChatViewer extends ManagedActivity implements
}
}
@Override
public
boolean
onEditorAction
(
TextView
view
,
int
actionId
,
KeyEvent
event
)
{
if
(
actionId
==
EditorInfo
.
IME_ACTION_SEND
)
{
sendMessage
();
return
true
;
}
return
false
;
}
private
boolean
selectChat
(
String
account
,
String
user
)
{
for
(
int
position
=
0
;
position
<
chatViewerAdapter
.
getCount
();
position
++)
if
(((
BaseEntity
)
chatViewerAdapter
.
getItem
(
position
)).
equals
(
...
...
src/com/xabber/android/ui/ChatViewerFragment.java
View file @
8599d1dc
package
com
.
xabber
.
android
.
ui
;
import
android.content.Context
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.support.v4.app.FragmentActivity
;
import
android.text.ClipboardManager
;
import
android.text.Editable
;
import
android.text.TextWatcher
;
import
android.view.ContextMenu
;
import
android.view.ContextMenu.ContextMenuInfo
;
import
android.view.KeyEvent
;
import
android.view.LayoutInflater
;
import
android.view.Menu
;
import
android.view.MenuItem
;
import
android.view.SubMenu
;
import
android.view.View
;
import
android.view.View.OnClickListener
;
import
android.view.View.OnCreateContextMenuListener
;
import
android.view.View.OnKeyListener
;
import
android.view.ViewGroup
;
import
android.view.animation.Animation
;
import
android.view.animation.Animation.AnimationListener
;
import
android.view.animation.AnimationUtils
;
import
android.view.inputmethod.EditorInfo
;
import
android.view.inputmethod.InputMethodManager
;
import
android.widget.AdapterView.AdapterContextMenuInfo
;
import
android.widget.EditText
;
import
android.widget.ImageView
;
import
android.widget.ListView
;
...
...
@@ -26,15 +35,18 @@ import com.xabber.android.data.Application;
import
com.xabber.android.data.LogManager
;
import
com.xabber.android.data.NetworkException
;
import
com.xabber.android.data.SettingsManager
;
import
com.xabber.android.data.SettingsManager.ChatsHideKeyboard
;
import
com.xabber.android.data.SettingsManager.SecurityOtrMode
;
import
com.xabber.android.data.extension.archive.MessageArchiveManager
;
import
com.xabber.android.data.extension.attention.AttentionManager
;
import
com.xabber.android.data.extension.cs.ChatStateManager
;
import
com.xabber.android.data.extension.muc.MUCManager
;
import
com.xabber.android.data.extension.muc.RoomChat
;
import
com.xabber.android.data.extension.muc.RoomState
;
import
com.xabber.android.data.extension.otr.OTRManager
;
import
com.xabber.android.data.extension.otr.SecurityLevel
;
import
com.xabber.android.data.message.AbstractChat
;
import
com.xabber.android.data.message.MessageItem
;
import
com.xabber.android.data.message.MessageManager
;
import
com.xabber.android.data.message.RegularChat
;
import
com.xabber.android.data.message.chat.ChatManager
;
...
...
@@ -42,14 +54,13 @@ import com.xabber.android.data.notification.NotificationManager;
import
com.xabber.android.data.roster.AbstractContact
;
import
com.xabber.android.data.roster.RosterManager
;
import
com.xabber.android.ui.adapter.ChatMessageAdapter
;
import
com.xabber.android.ui.adapter.OnTextChangedListener
;
import
com.xabber.android.ui.dialog.ChatExportDialogFragment
;
import
com.xabber.android.ui.helper.AbstractAvatarInflaterHelper
;
import
com.xabber.android.ui.helper.ContactTitleInflater
;
import
com.xabber.android.ui.widget.PageSwitcher
;
import
com.xabber.androiddev.R
;
public
class
ChatViewerFragment
{
public
class
ChatViewerFragment
implements
OnCreateContextMenuListener
{
/**
* Minimum number of new messages to be requested from the server side
...
...
@@ -118,6 +129,10 @@ public class ChatViewerFragment {
return
activity
.
getString
(
resId
,
formatArgs
);
}
private
void
registerForContextMenu
(
View
view
)
{
view
.
setOnCreateContextMenuListener
(
this
);
}
public
View
getView
()
{
return
view
;
}
...
...
@@ -162,11 +177,51 @@ public class ChatViewerFragment {
listView
.
setAdapter
(
chatMessageAdapter
);
view
.
findViewById
(
R
.
id
.
chat_send
).
setOnClickListener
(
(
OnClickListener
)
getActivity
());
titleView
.
setOnClickListener
((
OnClickListener
)
getActivity
());
inputView
.
setOnKeyListener
((
OnKeyListener
)
getActivity
());
inputView
.
setOnEditorActionListener
((
OnEditorActionListener
)
getActivity
());
new
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
sendMessage
();
}
});
titleView
.
setOnClickListener
(
new
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
int
size
=
listView
.
getCount
();
if
(
size
>
0
)
listView
.
setSelection
(
size
-
1
);
}
});
inputView
.
setOnKeyListener
(
new
OnKeyListener
()
{
@Override
public
boolean
onKey
(
View
view
,
int
keyCode
,
KeyEvent
event
)
{
if
(
event
.
getAction
()
==
KeyEvent
.
ACTION_DOWN
&&
keyCode
==
KeyEvent
.
KEYCODE_ENTER
&&
SettingsManager
.
chatsSendByEnter
())
{
sendMessage
();
return
true
;
}
return
false
;
}
});
inputView
.
setOnEditorActionListener
(
new
OnEditorActionListener
()
{
@Override
public
boolean
onEditorAction
(
TextView
view
,
int
actionId
,
KeyEvent
event
)
{
if
(
actionId
==
EditorInfo
.
IME_ACTION_SEND
)
{
sendMessage
();
return
true
;
}
return
false
;
}
});
inputView
.
addTextChangedListener
(
new
TextWatcher
()
{
@Override
...
...
@@ -180,15 +235,16 @@ public class ChatViewerFragment {
}
@Override
public
void
afterTextChanged
(
Editable
s
)
{
public
void
afterTextChanged
(
Editable
text
)
{
if
(
skipOnTextChanges
)
return
;
((
OnTextChangedListener
)
getActivity
()).
onTextChanged
(
inputView
,
s
);
String
account
=
chatMessageAdapter
.
getAccount
();
String
user
=
chatMessageAdapter
.
getUser
();
ChatStateManager
.
getInstance
().
onComposing
(
account
,
user
,
text
);
}
});
listView
.
setOnCreateContextMenuListener
(
getActivity
()
);
registerForContextMenu
(
listView
);
return
view
;
}
...
...
@@ -432,6 +488,63 @@ public class ChatViewerFragment {
return
true
;
}
@Override
public
void
onCreateContextMenu
(
ContextMenu
menu
,
View
view
,
ContextMenuInfo
menuInfo
)
{
// super.onCreateContextMenu(menu, view, menuInfo);
AdapterContextMenuInfo
info
=
(
AdapterContextMenuInfo
)
menuInfo
;
final
MessageItem
message
=
(
MessageItem
)
listView
.
getAdapter
()
.
getItem
(
info
.
position
);
if
(
message
!=
null
&&
message
.
getAction
()
!=
null
)
return
;
if
(
message
.
isError
())
{
menu
.
add
(
R
.
string
.
message_repeat
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
sendMessage
(
message
.
getText
());
return
true
;
}
});
}
menu
.
add
(
R
.
string
.
message_quote
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
insertText
(
"> "
+
message
.
getText
()
+
"\n"
);
return
true
;
}
});
menu
.
add
(
R
.
string
.
message_copy
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
((
ClipboardManager
)
getActivity
().
getSystemService
(
Context
.
CLIPBOARD_SERVICE
)).
setText
(
message
.
getSpannable
());
return
true
;
}
});
menu
.
add
(
R
.
string
.
message_remove
).
setOnMenuItemClickListener
(
new
MenuItem
.
OnMenuItemClickListener
()
{
@Override
public
boolean
onMenuItemClick
(
MenuItem
item
)
{
MessageManager
.
getInstance
().
removeMessage
(
message
);
onChatChange
(
false
);
return
true
;
}
});
}
public
void
setChat
(
AbstractChat
chat
)
{
final
String
account
=
chat
.
getAccount
();
final
String
user
=
chat
.
getUser
();
...
...
@@ -519,4 +632,58 @@ public class ChatViewerFragment {
handler
.
postDelayed
(
pagesHideRunnable
,
PAGES_HIDDER_DELAY
);
}
/**
* Insert additional text to the input.
*
* @param additional
*/
public
void
insertText
(
String
additional
)
{
String
source
=
inputView
.
getText
().
toString
();
int
selection
=
inputView
.
getSelectionEnd
();
if
(
selection
==
-
1
)
selection
=
source
.
length
();
else
if
(
selection
>
source
.
length
())
selection
=
source
.
length
();
String
before
=
source
.
substring
(
0
,
selection
);
String
after
=
source
.
substring
(
selection
);
if
(
before
.
length
()
>
0
&&
!
before
.
endsWith
(
"\n"
))
additional
=
"\n"
+
additional
;
inputView
.
setText
(
before
+
additional
+
after
);
inputView
.
setSelection
(
selection
+
additional
.
length
());
}
private
void
sendMessage
()
{
String
text
=
inputView
.
getText
().
toString
();
int
start
=
0
;
int
end
=
text
.
length
();
while
(
start
<
end
&&
(
text
.
charAt
(
start
)
==
' '
||
text
.
charAt
(
start
)
==
'\n'
))
start
+=
1
;
while
(
start
<
end
&&
(
text
.
charAt
(
end
-
1
)
==
' '
||
text
.
charAt
(
end
-
1
)
==
'\n'
))
end
-=
1
;
text
=
text
.
substring
(
start
,
end
);
if
(
""
.
equals
(
text
))
return
;
skipOnTextChanges
=
true
;
inputView
.
setText
(
""
);
skipOnTextChanges
=
false
;
sendMessage
(
text
);
((
ChatViewer
)
getActivity
()).
onSent
();
if
(
SettingsManager
.
chatsHideKeyboard
()
==
ChatsHideKeyboard
.
always
||
(
getActivity
().
getResources
().
getBoolean
(
R
.
bool
.
landscape
)
&&
SettingsManager
.
chatsHideKeyboard
()
==
ChatsHideKeyboard
.
landscape
))
{
InputMethodManager
imm
=
(
InputMethodManager
)
getActivity
()
.
getSystemService
(
Context
.
INPUT_METHOD_SERVICE
);
imm
.
hideSoftInputFromWindow
(
inputView
.
getWindowToken
(),
0
);
}
}
private
void
sendMessage
(
String
text
)
{
final
String
account
=
chatMessageAdapter
.
getAccount
();
final
String
user
=
chatMessageAdapter
.
getUser
();
MessageManager
.
getInstance
().
sendMessage
(
account
,
user
,
text
);
onChatChange
(
false
);
}
}
src/com/xabber/android/ui/adapter/ChatViewerAdapter.java
View file @
8599d1dc
...
...
@@ -128,6 +128,10 @@ public class ChatViewerAdapter extends BaseAdapter implements SaveStateAdapter,
((
ChatViewerFragment
)
view
.
getTag
()).
onPrepareOptionsMenu
(
menu
);
}
public
void
insertText
(
View
view
,
String
text
)
{
((
ChatViewerFragment
)
view
.
getTag
()).
insertText
(
text
);
}
@Override
public
void
onChange
()
{
activeChats
=
new
ArrayList
<
AbstractChat
>(
MessageManager
.
getInstance
()
...
...
src/com/xabber/android/ui/adapter/OnTextChangedListener.java
deleted
100644 → 0
View file @
3ffd3912
/**
* Copyright (c) 2013, Redsolution LTD. All rights reserved.
*
* This file is part of Xabber project; you can redistribute it and/or
* modify it under the terms of the GNU General Public License, Version 3.
*
* Xabber is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License,
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
package
com
.
xabber
.
android
.
ui
.
adapter
;
import
android.widget.EditText
;
/**
* Listener for text to be changed.
*
* @author alexander.ivanov
*
*/
public
interface
OnTextChangedListener
{
void
onTextChanged
(
EditText
editText
,
CharSequence
text
);
}
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