Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
com.ccwangluo.accelerator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
sheteng
com.ccwangluo.accelerator
Commits
ebcf5143
Commit
ebcf5143
authored
Feb 04, 2018
by
Mygod
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle errors in acl dialog more gracefully
parent
3975f3f4
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
110 additions
and
63 deletions
+110
-63
mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
...in/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
+98
-59
mobile/src/main/res/layout/dialog_acl_rule.xml
mobile/src/main/res/layout/dialog_acl_rule.xml
+12
-4
No files found.
mobile/src/main/java/com/github/shadowsocks/acl/CustomRulesFragment.kt
View file @
ebcf5143
...
@@ -20,13 +20,13 @@
...
@@ -20,13 +20,13 @@
package
com.github.shadowsocks.acl
package
com.github.shadowsocks.acl
import
android.annotation.TargetApi
import
android.content.ClipData
import
android.content.ClipData
import
android.content.ClipboardManager
import
android.content.ClipboardManager
import
android.content.Context
import
android.content.Context
import
android.os.Build
import
android.os.Build
import
android.os.Bundle
import
android.os.Bundle
import
android.support.design.widget.Snackbar
import
android.support.design.widget.Snackbar
import
android.support.design.widget.TextInputLayout
import
android.support.v4.content.ContextCompat
import
android.support.v4.content.ContextCompat
import
android.support.v7.app.AlertDialog
import
android.support.v7.app.AlertDialog
import
android.support.v7.widget.DefaultItemAnimator
import
android.support.v7.widget.DefaultItemAnimator
...
@@ -34,11 +34,10 @@ import android.support.v7.widget.LinearLayoutManager
...
@@ -34,11 +34,10 @@ import android.support.v7.widget.LinearLayoutManager
import
android.support.v7.widget.RecyclerView
import
android.support.v7.widget.RecyclerView
import
android.support.v7.widget.Toolbar
import
android.support.v7.widget.Toolbar
import
android.support.v7.widget.helper.ItemTouchHelper
import
android.support.v7.widget.helper.ItemTouchHelper
import
android.text.Editable
import
android.text.TextWatcher
import
android.view.*
import
android.view.*
import
android.widget.EditText
import
android.widget.*
import
android.widget.Spinner
import
android.widget.TextView
import
android.widget.Toast
import
com.futuremind.recyclerviewfastscroll.FastScroller
import
com.futuremind.recyclerviewfastscroll.FastScroller
import
com.futuremind.recyclerviewfastscroll.SectionTitleProvider
import
com.futuremind.recyclerviewfastscroll.SectionTitleProvider
import
com.github.shadowsocks.App.Companion.app
import
com.github.shadowsocks.App.Companion.app
...
@@ -51,6 +50,7 @@ import com.github.shadowsocks.utils.asIterable
...
@@ -51,6 +50,7 @@ import com.github.shadowsocks.utils.asIterable
import
com.github.shadowsocks.utils.resolveResourceId
import
com.github.shadowsocks.utils.resolveResourceId
import
com.github.shadowsocks.widget.UndoSnackbarManager
import
com.github.shadowsocks.widget.UndoSnackbarManager
import
java.net.IDN
import
java.net.IDN
import
java.net.MalformedURLException
import
java.net.URL
import
java.net.URL
import
java.util.*
import
java.util.*
...
@@ -71,6 +71,92 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
...
@@ -71,6 +71,92 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
Domain
,
Domain
,
Url
;
Url
;
}
}
private
inner
class
AclRuleDialog
(
item
:
Any
=
""
)
:
TextWatcher
,
AdapterView
.
OnItemSelectedListener
{
val
builder
:
AlertDialog
.
Builder
val
templateSelector
:
Spinner
val
editText
:
EditText
private
val
inputLayout
:
TextInputLayout
private
lateinit
var
dialog
:
AlertDialog
private
lateinit
var
positive
:
Button
init
{
val
activity
=
activity
!!
val
view
=
activity
.
layoutInflater
.
inflate
(
R
.
layout
.
dialog_acl_rule
,
null
)
templateSelector
=
view
.
findViewById
(
R
.
id
.
template_selector
)
editText
=
view
.
findViewById
(
R
.
id
.
content
)
inputLayout
=
view
.
findViewById
(
R
.
id
.
content_layout
)
when
(
item
)
{
is
String
->
{
val
match
=
PATTERN_DOMAIN
.
find
(
item
)
if
(
match
!=
null
)
{
templateSelector
.
setSelection
(
Template
.
Domain
.
ordinal
)
editText
.
setText
(
IDN
.
toUnicode
(
match
.
value
.
replace
(
"\\."
,
"."
),
IDN
.
ALLOW_UNASSIGNED
or
IDN
.
USE_STD3_ASCII_RULES
))
}
else
{
templateSelector
.
setSelection
(
Template
.
Generic
.
ordinal
)
editText
.
setText
(
item
)
}
}
is
URL
->
{
templateSelector
.
setSelection
(
Template
.
Url
.
ordinal
)
editText
.
setText
(
item
.
toString
())
}
else
->
{
templateSelector
.
setSelection
(
Template
.
Generic
.
ordinal
)
editText
.
setText
(
item
.
toString
())
}
}
templateSelector
.
onItemSelectedListener
=
this
editText
.
addTextChangedListener
(
this
)
builder
=
AlertDialog
.
Builder
(
activity
)
.
setTitle
(
R
.
string
.
edit_rule
)
.
setNegativeButton
(
android
.
R
.
string
.
cancel
,
null
)
.
setView
(
view
)
}
fun
show
()
{
dialog
=
builder
.
create
()
dialog
.
show
()
positive
=
dialog
.
getButton
(
AlertDialog
.
BUTTON_POSITIVE
)
validate
()
}
override
fun
beforeTextChanged
(
s
:
CharSequence
?,
start
:
Int
,
count
:
Int
,
after
:
Int
)
{
}
override
fun
onTextChanged
(
s
:
CharSequence
?,
start
:
Int
,
before
:
Int
,
count
:
Int
)
{
}
override
fun
afterTextChanged
(
s
:
Editable
)
=
validate
(
value
=
s
)
override
fun
onNothingSelected
(
parent
:
AdapterView
<
*
>?)
=
throw
IllegalStateException
()
override
fun
onItemSelected
(
parent
:
AdapterView
<
*
>?,
view
:
View
?,
position
:
Int
,
id
:
Long
)
=
validate
(
position
)
private
fun
validate
(
template
:
Int
=
templateSelector
.
selectedItemPosition
,
value
:
Editable
=
editText
.
text
)
{
val
error
=
when
(
Template
.
values
()[
template
])
{
Template
.
Generic
->
if
(
value
.
isEmpty
())
""
else
null
Template
.
Domain
->
try
{
IDN
.
toASCII
(
value
.
toString
(),
IDN
.
ALLOW_UNASSIGNED
or
IDN
.
USE_STD3_ASCII_RULES
)
null
}
catch
(
e
:
IllegalArgumentException
)
{
e
.
message
}
Template
.
Url
->
try
{
URL
(
value
.
toString
())
null
}
catch
(
e
:
MalformedURLException
)
{
e
.
message
}
}
inputLayout
.
error
=
error
positive
.
isEnabled
=
error
==
null
}
fun
add
():
Int
?
{
val
text
=
editText
.
text
.
toString
()
return
when
(
Template
.
values
()[
templateSelector
.
selectedItemPosition
])
{
Template
.
Generic
->
adapter
.
addToProxy
(
text
)
Template
.
Domain
->
adapter
.
addHostname
(
TEMPLATE_REGEX_DOMAIN
.
format
(
Locale
.
ENGLISH
,
IDN
.
toASCII
(
text
,
IDN
.
ALLOW_UNASSIGNED
or
IDN
.
USE_STD3_ASCII_RULES
).
replace
(
"."
,
"\\."
)))
Template
.
Url
->
adapter
.
addURL
(
URL
(
text
))
}
}
}
private
inner
class
AclRuleViewHolder
(
view
:
View
)
:
RecyclerView
.
ViewHolder
(
view
),
private
inner
class
AclRuleViewHolder
(
view
:
View
)
:
RecyclerView
.
ViewHolder
(
view
),
View
.
OnClickListener
,
View
.
OnLongClickListener
{
View
.
OnClickListener
,
View
.
OnLongClickListener
{
...
@@ -104,19 +190,18 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
...
@@ -104,19 +190,18 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
override
fun
onClick
(
v
:
View
?)
{
override
fun
onClick
(
v
:
View
?)
{
if
(
selectedItems
.
isNotEmpty
())
onLongClick
(
v
)
else
{
if
(
selectedItems
.
isNotEmpty
())
onLongClick
(
v
)
else
{
val
(
templateSelector
,
editText
,
dialog
)
=
create
AclRuleDialog
(
item
)
val
dialog
=
AclRuleDialog
(
item
)
dialog
dialog
.
builder
.
setNeutralButton
(
R
.
string
.
delete
,
{
_
,
_
->
.
setNeutralButton
(
R
.
string
.
delete
,
{
_
,
_
->
adapter
.
remove
(
item
)
adapter
.
remove
(
item
)
undoManager
.
remove
(
Pair
(-
1
,
item
))
undoManager
.
remove
(
Pair
(-
1
,
item
))
})
})
.
setPositiveButton
(
android
.
R
.
string
.
ok
,
{
_
,
_
->
.
setPositiveButton
(
android
.
R
.
string
.
ok
,
{
_
,
_
->
adapter
.
remove
(
item
)
adapter
.
remove
(
item
)
val
index
=
adapter
.
addFromTemplate
(
templateSelector
.
selectedItemPosition
,
val
index
=
dialog
.
add
()
?:
adapter
.
add
(
item
)
editText
.
text
.
toString
())
?:
adapter
.
add
(
item
)
if
(
index
!=
null
)
list
.
post
{
list
.
scrollToPosition
(
index
)
}
if
(
index
!=
null
)
list
.
post
{
list
.
scrollToPosition
(
index
)
}
})
})
.
create
()
.
show
()
dialog
.
show
()
}
}
}
}
override
fun
onLongClick
(
p0
:
View
?):
Boolean
{
override
fun
onLongClick
(
p0
:
View
?):
Boolean
{
...
@@ -208,20 +293,6 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
...
@@ -208,20 +293,6 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
.
forEach
{
if
(
result
==
null
)
result
=
it
}
.
forEach
{
if
(
result
==
null
)
result
=
it
}
return
result
return
result
}
}
fun
addFromTemplate
(
templateValue
:
Int
,
text
:
String
):
Int
?
{
val
template
=
Template
.
values
()[
templateValue
]
return
when
(
template
)
{
Template
.
Generic
->
addToProxy
(
text
)
Template
.
Domain
->
try
{
addHostname
(
TEMPLATE_REGEX_DOMAIN
.
format
(
Locale
.
ENGLISH
,
IDN
.
toASCII
(
text
,
IDN
.
ALLOW_UNASSIGNED
or
IDN
.
USE_STD3_ASCII_RULES
).
replace
(
"."
,
"\\."
)))
}
catch
(
exc
:
IllegalArgumentException
)
{
Toast
.
makeText
(
activity
,
exc
.
message
,
Toast
.
LENGTH_SHORT
).
show
()
null
}
Template
.
Url
->
addURL
(
URL
(
text
))
}
}
fun
remove
(
i
:
Int
)
{
fun
remove
(
i
:
Int
)
{
val
j
=
i
-
acl
.
subnets
.
size
()
val
j
=
i
-
acl
.
subnets
.
size
()
...
@@ -297,37 +368,6 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
...
@@ -297,37 +368,6 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
if
(
selectedItems
.
isEmpty
())
mode
?.
finish
()
else
if
(
mode
==
null
)
mode
=
toolbar
.
startActionMode
(
this
)
if
(
selectedItems
.
isEmpty
())
mode
?.
finish
()
else
if
(
mode
==
null
)
mode
=
toolbar
.
startActionMode
(
this
)
}
}
private
fun
createAclRuleDialog
(
item
:
Any
=
""
):
Triple
<
Spinner
,
EditText
,
AlertDialog
.
Builder
>
{
val
view
=
activity
!!
.
layoutInflater
.
inflate
(
R
.
layout
.
dialog_acl_rule
,
null
)
val
templateSelector
=
view
.
findViewById
<
Spinner
>(
R
.
id
.
template_selector
)
val
editText
=
view
.
findViewById
<
EditText
>(
R
.
id
.
content
)
when
(
item
)
{
is
String
->
{
val
match
=
PATTERN_DOMAIN
.
find
(
item
)
if
(
match
!=
null
)
{
templateSelector
.
setSelection
(
Template
.
Domain
.
ordinal
)
editText
.
setText
(
IDN
.
toUnicode
(
match
.
value
.
replace
(
"\\."
,
"."
),
IDN
.
ALLOW_UNASSIGNED
or
IDN
.
USE_STD3_ASCII_RULES
))
}
else
{
templateSelector
.
setSelection
(
Template
.
Generic
.
ordinal
)
editText
.
setText
(
item
)
}
}
is
URL
->
{
templateSelector
.
setSelection
(
Template
.
Url
.
ordinal
)
editText
.
setText
(
item
.
toString
())
}
else
->
{
templateSelector
.
setSelection
(
Template
.
Generic
.
ordinal
)
editText
.
setText
(
item
.
toString
())
}
}
return
Triple
(
templateSelector
,
editText
,
AlertDialog
.
Builder
(
activity
!!
)
.
setTitle
(
R
.
string
.
edit_rule
)
.
setNegativeButton
(
android
.
R
.
string
.
cancel
,
null
)
.
setView
(
view
))
}
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
override
fun
onCreateView
(
inflater
:
LayoutInflater
,
container
:
ViewGroup
?,
savedInstanceState
:
Bundle
?):
View
?
=
inflater
.
inflate
(
R
.
layout
.
layout_custom_rules
,
container
,
false
)
inflater
.
inflate
(
R
.
layout
.
layout_custom_rules
,
container
,
false
)
...
@@ -392,10 +432,9 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
...
@@ -392,10 +432,9 @@ class CustomRulesFragment : ToolbarFragment(), Toolbar.OnMenuItemClickListener,
override
fun
onMenuItemClick
(
item
:
MenuItem
):
Boolean
=
when
(
item
.
itemId
)
{
override
fun
onMenuItemClick
(
item
:
MenuItem
):
Boolean
=
when
(
item
.
itemId
)
{
R
.
id
.
action_manual_settings
->
{
R
.
id
.
action_manual_settings
->
{
val
(
templateSelector
,
editText
,
dialog
)
=
createAclRuleDialog
()
val
dialog
=
AclRuleDialog
()
dialog
.
setPositiveButton
(
android
.
R
.
string
.
ok
,
{
_
,
_
->
dialog
.
builder
.
setPositiveButton
(
android
.
R
.
string
.
ok
,
{
_
,
_
->
dialog
.
add
()
})
adapter
.
addFromTemplate
(
templateSelector
.
selectedItemPosition
,
editText
.
text
.
toString
())
dialog
.
show
()
}).
create
().
show
()
true
true
}
}
R
.
id
.
action_import
->
{
R
.
id
.
action_import
->
{
...
...
mobile/src/main/res/layout/dialog_acl_rule.xml
View file @
ebcf5143
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:orientation=
"vertical"
android:orientation=
"vertical"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
>
android:layout_height=
"match_parent"
>
...
@@ -8,8 +9,15 @@
...
@@ -8,8 +9,15 @@
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:labelFor=
"@+id/content"
android:labelFor=
"@+id/content"
android:entries=
"@array/acl_rule_templates"
/>
android:entries=
"@array/acl_rule_templates"
/>
<EditText
android:id=
"@+id/content"
<android.support.design.widget.TextInputLayout
android:id=
"@+id/content_layout"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
app:errorEnabled=
"true"
>
<android.support.design.widget.TextInputEditText
android:id=
"@+id/content"
android:layout_width=
"match_parent"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:layout_height=
"wrap_content"
android:inputType=
"textNoSuggestions|textMultiLine"
/>
android:inputType=
"textNoSuggestions|textMultiLine"
/>
</android.support.design.widget.TextInputLayout>
</LinearLayout>
</LinearLayout>
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