Commit 5c53a2a7 authored by Max Lv's avatar Max Lv

refine UI

parent c4c74c01
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
<string name="initializing">Initializing…</string> <string name="initializing">Initializing…</string>
<string name="recovering">Reseting…</string> <string name="recovering">Reseting…</string>
<string name="loading">Loading app list…</string> <string name="loading">Loading app list…</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="remove_profile">Remove this profile?</string>
<!-- menu category --> <!-- menu category -->
<string name="recovery">Reset</string> <string name="recovery">Reset</string>
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.github.shadowsocks.preferences.SummaryEditTextPreference <com.github.shadowsocks.preferences.ProfileEditTextPreference
android:defaultValue="Default" android:defaultValue="Default"
android:key="profileName" android:key="profileName"
android:summary="@string/profile_summary" android:summary="@string/profile_summary"
android:title="@string/profile"> android:title="@string/profile">
</com.github.shadowsocks.preferences.SummaryEditTextPreference> </com.github.shadowsocks.preferences.ProfileEditTextPreference>
<com.github.shadowsocks.preferences.SummaryEditTextPreference <com.github.shadowsocks.preferences.SummaryEditTextPreference
android:defaultValue="198.199.101.152" android:defaultValue="198.199.101.152"
android:key="proxy" android:key="proxy"
......
...@@ -60,7 +60,6 @@ import android.net.{Uri, VpnService} ...@@ -60,7 +60,6 @@ import android.net.{Uri, VpnService}
import android.webkit.{WebViewClient, WebView} import android.webkit.{WebViewClient, WebView}
import android.app.backup.BackupManager import android.app.backup.BackupManager
import scala.concurrent.ops._ import scala.concurrent.ops._
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import com.google.ads.{AdRequest, AdSize, AdView} import com.google.ads.{AdRequest, AdSize, AdView}
import net.simonvt.menudrawer.MenuDrawer import net.simonvt.menudrawer.MenuDrawer
...@@ -72,7 +71,7 @@ import com.nostra13.universalimageloader.core.download.BaseImageDownloader ...@@ -72,7 +71,7 @@ import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import com.github.shadowsocks.database.Item import com.github.shadowsocks.database.Item
import com.github.shadowsocks.database.Category import com.github.shadowsocks.database.Category
import com.actionbarsherlock.view.MenuItem import com.actionbarsherlock.view.MenuItem
import com.github.shadowsocks.preferences.{PasswordEditTextPreference, SummaryEditTextPreference} import com.github.shadowsocks.preferences.{ProfileEditTextPreference, PasswordEditTextPreference, SummaryEditTextPreference}
import com.github.shadowsocks.database.Item import com.github.shadowsocks.database.Item
import com.github.shadowsocks.database.Category import com.github.shadowsocks.database.Category
import scala.Option import scala.Option
...@@ -148,13 +147,19 @@ object Shadowsocks { ...@@ -148,13 +147,19 @@ object Shadowsocks {
pref.asInstanceOf[SummaryEditTextPreference].setText(value) pref.asInstanceOf[SummaryEditTextPreference].setText(value)
} }
def updateProfileEditTextPreference(pref: Preference, value: String) {
pref.asInstanceOf[ProfileEditTextPreference].resetSummary(value)
pref.asInstanceOf[ProfileEditTextPreference].setText(value)
}
def updateCheckBoxPreference(pref: Preference, value: Boolean) { def updateCheckBoxPreference(pref: Preference, value: Boolean) {
pref.asInstanceOf[CheckBoxPreference].setChecked(value) pref.asInstanceOf[CheckBoxPreference].setChecked(value)
} }
def updatePreference(pref: Preference, name: String, profile: Profile) { def updatePreference(pref: Preference, name: String, profile: Profile) {
name match { name match {
case Key.profileName => updateSummaryEditTextPreference(pref, profile.name) case Key.profileName => updateProfileEditTextPreference(pref, profile.name)
case Key.proxy => updateSummaryEditTextPreference(pref, profile.host) case Key.proxy => updateSummaryEditTextPreference(pref, profile.host)
case Key.remotePort => updateSummaryEditTextPreference(pref, profile.remotePort.toString) case Key.remotePort => updateSummaryEditTextPreference(pref, profile.remotePort.toString)
case Key.localPort => updateSummaryEditTextPreference(pref, profile.localPort.toString) case Key.localPort => updateSummaryEditTextPreference(pref, profile.localPort.toString)
...@@ -283,7 +288,6 @@ object Shadowsocks { ...@@ -283,7 +288,6 @@ object Shadowsocks {
class Shadowsocks class Shadowsocks
extends UnifiedSherlockPreferenceActivity extends UnifiedSherlockPreferenceActivity
with CompoundButton.OnCheckedChangeListener with CompoundButton.OnCheckedChangeListener
with OnSharedPreferenceChangeListener
with MenuAdapter.MenuListener{ with MenuAdapter.MenuListener{
private val MSG_CRASH_RECOVER: Int = 1 private val MSG_CRASH_RECOVER: Int = 1
...@@ -300,7 +304,8 @@ class Shadowsocks ...@@ -300,7 +304,8 @@ class Shadowsocks
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this) lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE) lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE)
lazy val receiver = new StateBroadcastReceiver lazy val stateReceiver = new StateBroadcastReceiver
lazy val preferenceReceiver = new PreferenceBroadcastReceiver
lazy val drawer = MenuDrawer.attach(this) lazy val drawer = MenuDrawer.attach(this)
lazy val menuAdapter = new MenuAdapter(this, getMenuList) lazy val menuAdapter = new MenuAdapter(this, getMenuList)
lazy val listView = new ListView(this) lazy val listView = new ListView(this)
...@@ -319,6 +324,16 @@ class Shadowsocks ...@@ -319,6 +324,16 @@ class Shadowsocks
} }
} }
private def showProgress(msg: String): Handler = {
clearDialog()
progressDialog = ProgressDialog.show(this, "", msg, true, false)
new Handler {
override def handleMessage(msg: Message) {
clearDialog()
}
}
}
private def copyAssets(path: String) { private def copyAssets(path: String) {
val assetManager: AssetManager = getAssets val assetManager: AssetManager = getAssets
var files: Array[String] = null var files: Array[String] = null
...@@ -366,13 +381,6 @@ class Shadowsocks ...@@ -366,13 +381,6 @@ class Shadowsocks
} }
} }
override def onSharedPreferenceChanged(prefs: SharedPreferences, key: String) {
if (key == Key.profileName) {
profileManager.save()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
}
}
private def crash_recovery() { private def crash_recovery() {
val sb = new StringBuilder val sb = new StringBuilder
...@@ -415,9 +423,7 @@ class Shadowsocks ...@@ -415,9 +423,7 @@ class Shadowsocks
} }
def prepareStartService() { def prepareStartService() {
clearDialog() showProgress(getString(R.string.connecting))
progressDialog = ProgressDialog
.show(Shadowsocks.this, "", getString(R.string.connecting), true, true)
spawn { spawn {
if (isVpnEnabled) { if (isVpnEnabled) {
val intent = VpnService.prepare(this) val intent = VpnService.prepare(this)
...@@ -509,7 +515,9 @@ class Shadowsocks ...@@ -509,7 +515,9 @@ class Shadowsocks
title.setText(R.string.app_name) title.setText(R.string.app_name)
switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch] switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch]
registerReceiver(receiver, new IntentFilter(Action.UPDATE_STATE))
registerReceiver(stateReceiver, new IntentFilter(Action.UPDATE_STATE))
registerReceiver(preferenceReceiver, new IntentFilter(Action.UPDATE_PREFS))
val init: Boolean = !Shadowsocks.isServiceStarted(this) val init: Boolean = !Shadowsocks.isServiceStarted(this)
if (init) { if (init) {
...@@ -554,12 +562,15 @@ class Shadowsocks ...@@ -554,12 +562,15 @@ class Shadowsocks
def addProfile(id: Int) { def addProfile(id: Int) {
drawer.closeMenu(true) drawer.closeMenu(true)
val h = showProgress(getString(R.string.loading))
handler.postDelayed(new Runnable { handler.postDelayed(new Runnable {
def run() { def run() {
Shadowsocks.currentProfile = profileManager.reload(id) Shadowsocks.currentProfile = profileManager.reload(id)
updatePreferenceScreen() updatePreferenceScreen()
profileManager.save() profileManager.save()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id) menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
h.sendEmptyMessage(0)
} }
}, 600) }, 600)
...@@ -569,12 +580,15 @@ class Shadowsocks ...@@ -569,12 +580,15 @@ class Shadowsocks
def updateProfile(id: Int) { def updateProfile(id: Int) {
drawer.closeMenu(true) drawer.closeMenu(true)
val h = showProgress(getString(R.string.loading))
handler.postDelayed(new Runnable { handler.postDelayed(new Runnable {
def run() { def run() {
Shadowsocks.currentProfile = profileManager.reload(id) Shadowsocks.currentProfile = profileManager.reload(id)
updatePreferenceScreen() updatePreferenceScreen()
menuAdapter.setActiveId(id) menuAdapter.setActiveId(id)
menuAdapter.notifyDataSetChanged() menuAdapter.notifyDataSetChanged()
h.sendEmptyMessage(0)
} }
}, 600) }, 600)
...@@ -584,8 +598,14 @@ class Shadowsocks ...@@ -584,8 +598,14 @@ class Shadowsocks
def delProfile(id: Int): Boolean = { def delProfile(id: Int): Boolean = {
drawer.closeMenu(true) drawer.closeMenu(true)
handler.postDelayed(new Runnable { new AlertDialog.Builder(this)
def run() { .setMessage(R.string.remove_profile)
.setCancelable(false)
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, i: Int) = dialog.cancel()
})
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
override def onClick(dialog: DialogInterface, i: Int) {
profileManager.delProfile(id) profileManager.delProfile(id)
val profileId = { val profileId = {
val profiles = profileManager.getAllProfiles.getOrElse(List[Profile]()) val profiles = profileManager.getAllProfiles.getOrElse(List[Profile]())
...@@ -594,8 +614,9 @@ class Shadowsocks ...@@ -594,8 +614,9 @@ class Shadowsocks
Shadowsocks.currentProfile = profileManager.load(profileId) Shadowsocks.currentProfile = profileManager.load(profileId)
updatePreferenceScreen() updatePreferenceScreen()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id) menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
dialog.dismiss()
} }
}, 600) }).create().show()
if (!isSinglePane) sendBroadcast(new Intent(Action.UPDATE_FRAGMENT)) if (!isSinglePane) sendBroadcast(new Intent(Action.UPDATE_FRAGMENT))
...@@ -652,7 +673,6 @@ class Shadowsocks ...@@ -652,7 +673,6 @@ class Shadowsocks
protected override def onPause() { protected override def onPause() {
super.onPause() super.onPause()
prepared = false prepared = false
settings.unregisterOnSharedPreferenceChangeListener(this)
} }
protected override def onResume() { protected override def onResume() {
...@@ -687,7 +707,6 @@ class Shadowsocks ...@@ -687,7 +707,6 @@ class Shadowsocks
switchButton.setOnCheckedChangeListener(this) switchButton.setOnCheckedChangeListener(this)
settings.registerOnSharedPreferenceChangeListener(this)
} }
private def setPreferenceEnabled(enabled: Boolean) { private def setPreferenceEnabled(enabled: Boolean) {
...@@ -737,7 +756,8 @@ class Shadowsocks ...@@ -737,7 +756,8 @@ class Shadowsocks
override def onDestroy() { override def onDestroy() {
super.onDestroy() super.onDestroy()
Crouton.cancelAllCroutons() Crouton.cancelAllCroutons()
unregisterReceiver(receiver) unregisterReceiver(stateReceiver)
unregisterReceiver(preferenceReceiver)
new BackupManager(this).dataChanged() new BackupManager(this).dataChanged()
} }
...@@ -752,13 +772,8 @@ class Shadowsocks ...@@ -752,13 +772,8 @@ class Shadowsocks
} }
private def recovery() { private def recovery() {
clearDialog() val h = showProgress(getString(R.string.recovering))
progressDialog = ProgressDialog.show(this, "", getString(R.string.recovering), true, true)
val h: Handler = new Handler {
override def handleMessage(msg: Message) {
clearDialog()
}
}
serviceStop() serviceStop()
spawn { spawn {
reset() reset()
...@@ -767,13 +782,7 @@ class Shadowsocks ...@@ -767,13 +782,7 @@ class Shadowsocks
} }
private def flushDnsCache() { private def flushDnsCache() {
clearDialog() val h = showProgress(getString(R.string.flushing))
progressDialog = ProgressDialog.show(this, "", getString(R.string.flushing), true, true)
val h: Handler = new Handler {
override def handleMessage(msg: Message) {
clearDialog()
}
}
spawn { spawn {
Utils.toggleAirplaneMode(getBaseContext) Utils.toggleAirplaneMode(getBaseContext)
h.sendEmptyMessage(0) h.sendEmptyMessage(0)
...@@ -945,6 +954,13 @@ class Shadowsocks ...@@ -945,6 +954,13 @@ class Shadowsocks
} }
} }
class PreferenceBroadcastReceiver extends BroadcastReceiver {
override def onReceive(context: Context, intent: Intent) {
Shadowsocks.currentProfile = profileManager.save()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
}
}
class StateBroadcastReceiver extends BroadcastReceiver { class StateBroadcastReceiver extends BroadcastReceiver {
override def onReceive(context: Context, intent: Intent) { override def onReceive(context: Context, intent: Intent) {
val state = intent.getIntExtra(Extra.STATE, State.INIT) val state = intent.getIntExtra(Extra.STATE, State.INIT)
......
...@@ -157,6 +157,7 @@ object Action { ...@@ -157,6 +157,7 @@ object Action {
val CLOSE = "com.github.shadowsocks.ACTION_SHUTDOWN" val CLOSE = "com.github.shadowsocks.ACTION_SHUTDOWN"
val UPDATE_STATE = "com.github.shadowsocks.ACTION_UPDATE_STATE" val UPDATE_STATE = "com.github.shadowsocks.ACTION_UPDATE_STATE"
val UPDATE_FRAGMENT = "com.github.shadowsocks.ACTION_UPDATE_FRAGMENT" val UPDATE_FRAGMENT = "com.github.shadowsocks.ACTION_UPDATE_FRAGMENT"
val UPDATE_PREFS = "com.github.shadowsocks.ACTION_UPDATE_PREFS"
} }
object Extra { object Extra {
......
...@@ -56,6 +56,17 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) { ...@@ -56,6 +56,17 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
} }
} }
def updateProfile(profile: Profile): Boolean = {
try {
dbHelper.profileDao.update(profile)
true
} catch {
case ex: Exception =>
Log.e(Shadowsocks.TAG, "addProfile", ex)
false
}
}
def getProfile(id: Int): Option[Profile] = { def getProfile(id: Int): Option[Profile] = {
try { try {
dbHelper.profileDao.queryForId(id) match { dbHelper.profileDao.queryForId(id) match {
...@@ -122,9 +133,11 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) { ...@@ -122,9 +133,11 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
profile profile
} }
def save() { def save(): Profile = {
val profile = new Profile() val profile = new Profile()
profile.id = settings.getInt(Key.profileId, -1)
profile.global = settings.getBoolean(Key.isGlobalProxy, false) profile.global = settings.getBoolean(Key.isGlobalProxy, false)
profile.chnroute = settings.getBoolean(Key.isGFWList, false) profile.chnroute = settings.getBoolean(Key.isGFWList, false)
profile.bypass = settings.getBoolean(Key.isBypassApps, false) profile.bypass = settings.getBoolean(Key.isBypassApps, false)
...@@ -149,10 +162,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) { ...@@ -149,10 +162,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
} }
profile.individual = settings.getString(Key.proxied, "") profile.individual = settings.getString(Key.proxied, "")
profile.id = settings.getInt(Key.profileId, -1) updateProfile(profile)
Log.d(Shadowsocks.TAG, "save " + profile.id + " " + profile.name)
createOrUpdateProfile(profile) profile
} }
} }
/*
* Shadowsocks - A shadowsocks client for Android
* Copyright (C) 2013 <max.c.lv@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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/>.
*
*
* ___====-_ _-====___
* _--^^^#####// \\#####^^^--_
* _-^##########// ( ) \\##########^-_
* -############// |\^^/| \\############-
* _/############// (@::@) \\############\_
* /#############(( \\// ))#############\
* -###############\\ (oo) //###############-
* -#################\\ / VV \ //#################-
* -###################\\/ \//###################-
* _#/|##########/\######( /\ )######/\##########|\#_
* |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \|
* ` |/ V V ` V \#\| | | |/#/ V ' V V \| '
* ` ` ` ` / | | | | \ ' ' ' '
* ( | | | | )
* __\ | | | | /__
* (vvv(VVV)(VVV)vvv)
*
* HERE BE DRAGONS
*
*/
package com.github.shadowsocks.preferences
import android.content.{Intent, Context}
import android.preference.EditTextPreference
import android.util.AttributeSet
import com.github.shadowsocks.Action
class ProfileEditTextPreference(context: Context, attrs: AttributeSet, defStyle: Int)
extends EditTextPreference(context, attrs, defStyle) {
def this(context: Context, attrs: AttributeSet) = {
this(context, attrs, android.R.attr.editTextPreferenceStyle)
mDefaultSummary = getSummary
}
override def setSummary(summary: CharSequence) {
if (summary.toString.isEmpty) {
super.setSummary(mDefaultSummary)
} else {
super.setSummary(summary)
}
context.sendBroadcast(new Intent(Action.UPDATE_PREFS))
}
def resetSummary(summary: CharSequence) {
if (summary.toString.isEmpty) {
super.setSummary(mDefaultSummary)
} else {
super.setSummary(summary)
}
}
private var mDefaultSummary: CharSequence = getSummary
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment