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

refine UI

parent c4c74c01
......@@ -68,6 +68,9 @@
<string name="initializing">Initializing…</string>
<string name="recovering">Reseting…</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 -->
<string name="recovery">Reset</string>
......
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<com.github.shadowsocks.preferences.SummaryEditTextPreference
<com.github.shadowsocks.preferences.ProfileEditTextPreference
android:defaultValue="Default"
android:key="profileName"
android:summary="@string/profile_summary"
android:title="@string/profile">
</com.github.shadowsocks.preferences.SummaryEditTextPreference>
</com.github.shadowsocks.preferences.ProfileEditTextPreference>
<com.github.shadowsocks.preferences.SummaryEditTextPreference
android:defaultValue="198.199.101.152"
android:key="proxy"
......
......@@ -60,7 +60,6 @@ import android.net.{Uri, VpnService}
import android.webkit.{WebViewClient, WebView}
import android.app.backup.BackupManager
import scala.concurrent.ops._
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import com.google.ads.{AdRequest, AdSize, AdView}
import net.simonvt.menudrawer.MenuDrawer
......@@ -72,7 +71,7 @@ import com.nostra13.universalimageloader.core.download.BaseImageDownloader
import com.github.shadowsocks.database.Item
import com.github.shadowsocks.database.Category
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.Category
import scala.Option
......@@ -148,13 +147,19 @@ object Shadowsocks {
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) {
pref.asInstanceOf[CheckBoxPreference].setChecked(value)
}
def updatePreference(pref: Preference, name: String, profile: Profile) {
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.remotePort => updateSummaryEditTextPreference(pref, profile.remotePort.toString)
case Key.localPort => updateSummaryEditTextPreference(pref, profile.localPort.toString)
......@@ -283,7 +288,6 @@ object Shadowsocks {
class Shadowsocks
extends UnifiedSherlockPreferenceActivity
with CompoundButton.OnCheckedChangeListener
with OnSharedPreferenceChangeListener
with MenuAdapter.MenuListener{
private val MSG_CRASH_RECOVER: Int = 1
......@@ -300,7 +304,8 @@ class Shadowsocks
lazy val settings = PreferenceManager.getDefaultSharedPreferences(this)
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 menuAdapter = new MenuAdapter(this, getMenuList)
lazy val listView = new ListView(this)
......@@ -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) {
val assetManager: AssetManager = getAssets
var files: Array[String] = null
......@@ -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() {
val sb = new StringBuilder
......@@ -415,9 +423,7 @@ class Shadowsocks
}
def prepareStartService() {
clearDialog()
progressDialog = ProgressDialog
.show(Shadowsocks.this, "", getString(R.string.connecting), true, true)
showProgress(getString(R.string.connecting))
spawn {
if (isVpnEnabled) {
val intent = VpnService.prepare(this)
......@@ -509,7 +515,9 @@ class Shadowsocks
title.setText(R.string.app_name)
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)
if (init) {
......@@ -554,12 +562,15 @@ class Shadowsocks
def addProfile(id: Int) {
drawer.closeMenu(true)
val h = showProgress(getString(R.string.loading))
handler.postDelayed(new Runnable {
def run() {
Shadowsocks.currentProfile = profileManager.reload(id)
updatePreferenceScreen()
profileManager.save()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
h.sendEmptyMessage(0)
}
}, 600)
......@@ -569,12 +580,15 @@ class Shadowsocks
def updateProfile(id: Int) {
drawer.closeMenu(true)
val h = showProgress(getString(R.string.loading))
handler.postDelayed(new Runnable {
def run() {
Shadowsocks.currentProfile = profileManager.reload(id)
updatePreferenceScreen()
menuAdapter.setActiveId(id)
menuAdapter.notifyDataSetChanged()
h.sendEmptyMessage(0)
}
}, 600)
......@@ -584,18 +598,25 @@ class Shadowsocks
def delProfile(id: Int): Boolean = {
drawer.closeMenu(true)
handler.postDelayed(new Runnable {
def run() {
profileManager.delProfile(id)
val profileId = {
val profiles = profileManager.getAllProfiles.getOrElse(List[Profile]())
if (profiles.isEmpty) -1 else profiles(0).id
new AlertDialog.Builder(this)
.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)
val profileId = {
val profiles = profileManager.getAllProfiles.getOrElse(List[Profile]())
if (profiles.isEmpty) -1 else profiles(0).id
}
Shadowsocks.currentProfile = profileManager.load(profileId)
updatePreferenceScreen()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
dialog.dismiss()
}
Shadowsocks.currentProfile = profileManager.load(profileId)
updatePreferenceScreen()
menuAdapter.updateList(getMenuList, Shadowsocks.currentProfile.id)
}
}, 600)
}).create().show()
if (!isSinglePane) sendBroadcast(new Intent(Action.UPDATE_FRAGMENT))
......@@ -652,7 +673,6 @@ class Shadowsocks
protected override def onPause() {
super.onPause()
prepared = false
settings.unregisterOnSharedPreferenceChangeListener(this)
}
protected override def onResume() {
......@@ -687,7 +707,6 @@ class Shadowsocks
switchButton.setOnCheckedChangeListener(this)
settings.registerOnSharedPreferenceChangeListener(this)
}
private def setPreferenceEnabled(enabled: Boolean) {
......@@ -737,7 +756,8 @@ class Shadowsocks
override def onDestroy() {
super.onDestroy()
Crouton.cancelAllCroutons()
unregisterReceiver(receiver)
unregisterReceiver(stateReceiver)
unregisterReceiver(preferenceReceiver)
new BackupManager(this).dataChanged()
}
......@@ -752,13 +772,8 @@ class Shadowsocks
}
private def recovery() {
clearDialog()
progressDialog = ProgressDialog.show(this, "", getString(R.string.recovering), true, true)
val h: Handler = new Handler {
override def handleMessage(msg: Message) {
clearDialog()
}
}
val h = showProgress(getString(R.string.recovering))
serviceStop()
spawn {
reset()
......@@ -767,13 +782,7 @@ class Shadowsocks
}
private def flushDnsCache() {
clearDialog()
progressDialog = ProgressDialog.show(this, "", getString(R.string.flushing), true, true)
val h: Handler = new Handler {
override def handleMessage(msg: Message) {
clearDialog()
}
}
val h = showProgress(getString(R.string.flushing))
spawn {
Utils.toggleAirplaneMode(getBaseContext)
h.sendEmptyMessage(0)
......@@ -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 {
override def onReceive(context: Context, intent: Intent) {
val state = intent.getIntExtra(Extra.STATE, State.INIT)
......
......@@ -157,6 +157,7 @@ object Action {
val CLOSE = "com.github.shadowsocks.ACTION_SHUTDOWN"
val UPDATE_STATE = "com.github.shadowsocks.ACTION_UPDATE_STATE"
val UPDATE_FRAGMENT = "com.github.shadowsocks.ACTION_UPDATE_FRAGMENT"
val UPDATE_PREFS = "com.github.shadowsocks.ACTION_UPDATE_PREFS"
}
object Extra {
......
......@@ -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] = {
try {
dbHelper.profileDao.queryForId(id) match {
......@@ -122,9 +133,11 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
profile
}
def save() {
def save(): Profile = {
val profile = new Profile()
profile.id = settings.getInt(Key.profileId, -1)
profile.global = settings.getBoolean(Key.isGlobalProxy, false)
profile.chnroute = settings.getBoolean(Key.isGFWList, false)
profile.bypass = settings.getBoolean(Key.isBypassApps, false)
......@@ -149,10 +162,8 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) {
}
profile.individual = settings.getString(Key.proxied, "")
profile.id = settings.getInt(Key.profileId, -1)
Log.d(Shadowsocks.TAG, "save " + profile.id + " " + profile.name)
updateProfile(profile)
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