diff --git a/build.sbt b/build.sbt index db33d8df..0a01f5e0 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,6 @@ libraryDependencies ++= Seq( "com.google.android" % "support-v4" % "r12", "com.google.android.analytics" % "analytics" % "2.0beta4", "dnsjava" % "dnsjava" % "2.1.5", - "com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4", "com.google.android.admob" % "admob" % "6.3.1" ) @@ -10,6 +9,13 @@ libraryDependencies ++= Seq( "com.actionbarsherlock" % "actionbarsherlock" % "4.4.0" artifacts(Artifact("actionbarsherlock", "apklib", "apklib")), "net.saik0.android.unifiedpreference" % "unifiedpreference" % "0.0.2" artifacts(Artifact("unifiedpreference", "apklib", "apklib")), "org.jraf" % "android-switch-backport" % "1.0" artifacts(Artifact("android-switch-backport", "apklib", "apklib")), - "de.keyboardsurfer.android.widget" % "crouton" % "1.7" + "net.simonvt.menudrawer" % "menudrawer" % "3.0.4" artifacts(Artifact("menudrawer", "apklib", "apklib")) +) + +libraryDependencies ++= Seq( + "de.keyboardsurfer.android.widget" % "crouton" % "1.7", + "com.nostra13.universalimageloader" % "universal-image-loader" % "1.8.4", + "com.j256.ormlite" % "ormlite-core" % "4.47", + "com.j256.ormlite" % "ormlite-android" % "4.47" ) diff --git a/project/Build.scala b/project/Build.scala index 822738a0..55aa12fb 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -5,8 +5,8 @@ import sbtandroid._ import sbtandroid.AndroidPlugin._ object App { - val version = "1.8.3" - val versionCode = 48 + val version = "1.9.0" + val versionCode = 50 } object General { @@ -28,6 +28,7 @@ object General { "-keep interface com.actionbarsherlock.** { *; }", "-keep class org.jraf.android.backport.** { *; }", "-keep class com.github.shadowsocks.** { *; }", + "-keep class * extends com.j256.ormlite.** { *; }", "-keepattributes *Annotation*") val proguardSettings = Seq ( @@ -36,8 +37,7 @@ object General { ) val miscSettings = Seq ( - cachePasswords := true, - publicServer := "127.0.0.1" + cachePasswords := true ) lazy val fullAndroidSettings = diff --git a/project/plugins.sbt b/project/plugins.sbt index b17b415f..3bbacfde 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,4 +6,4 @@ resolvers += Resolver.url("madeye private releases", new URL("http://madeye-mave addSbtPlugin("org.scala-sbt" % "sbt-android" % "0.7.1-SNAPSHOT") -addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.4.0") +addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.5.1") diff --git a/src/main/res/drawable-hdpi/ic_drawer.png b/src/main/res/drawable-hdpi/ic_drawer.png new file mode 100644 index 00000000..ec8c51f8 Binary files /dev/null and b/src/main/res/drawable-hdpi/ic_drawer.png differ diff --git a/src/main/res/drawable-mdpi/ic_drawer.png b/src/main/res/drawable-mdpi/ic_drawer.png new file mode 100644 index 00000000..7420a68d Binary files /dev/null and b/src/main/res/drawable-mdpi/ic_drawer.png differ diff --git a/src/main/res/drawable-xhdpi/ic_drawer.png b/src/main/res/drawable-xhdpi/ic_drawer.png new file mode 100644 index 00000000..7ffbe5c5 Binary files /dev/null and b/src/main/res/drawable-xhdpi/ic_drawer.png differ diff --git a/src/main/res/layout/layout_switch.xml b/src/main/res/layout/layout_switch.xml index b9e1c86f..51ca4b72 100644 --- a/src/main/res/layout/layout_switch.xml +++ b/src/main/res/layout/layout_switch.xml @@ -9,8 +9,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" - android:layout_marginLeft="16dp" - android:textSize="28sp" + android:textSize="22sp" android:textColor="@color/title" android:text="@string/app_name" android:layout_alignParentLeft="true" diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 5852b46b..8760a48c 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -45,7 +45,7 @@ import android.graphics.Typeface import android.os._ import android.preference.{Preference, PreferenceManager} import android.util.Log -import android.view.{ViewParent, KeyEvent} +import android.view.{ViewGroup, Gravity, ViewParent, KeyEvent} import android.widget.{LinearLayout, CompoundButton, RelativeLayout, TextView} import com.actionbarsherlock.view.Menu import com.actionbarsherlock.view.MenuItem @@ -67,6 +67,8 @@ 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 +import javax.swing.text.html.ListView object Shadowsocks { @@ -212,11 +214,14 @@ class Shadowsocks private var switchButton: Switch = null private var progressDialog: ProgressDialog = null - private var settings: SharedPreferences = null - private var status: SharedPreferences = null - private var prepared = false + private var state = State.INIT - private var receiver: StateBroadcastReceiver = null + private var prepared = false + + lazy val settings = PreferenceManager.getDefaultSharedPreferences(this) + lazy val status = getSharedPreferences(Key.status, Context.MODE_PRIVATE) + lazy val receiver = new StateBroadcastReceiver + lazy val drawer = MenuDrawer.attach(this) private val handler: Handler = new Handler { override def handleMessage(msg: Message) { @@ -366,7 +371,7 @@ class Shadowsocks } } - def initAdView() { + def initAdView(layoutResId: Int) { if (settings.getString(Key.proxy, "") == "198.199.101.152") { val adView = { if (isSinglePane) { @@ -375,7 +380,7 @@ class Shadowsocks new AdView(this, AdSize.BANNER, "a151becb8068b09") } } - val layoutView = getLayoutView(getListView.asInstanceOf[ViewParent]) + val layoutView = findViewById(layoutResId).asInstanceOf[ViewGroup] if (layoutView != null) { layoutView.addView(adView, 0) adView.loadAd(new AdRequest) @@ -383,18 +388,35 @@ class Shadowsocks } } + override def setContentView(layoutResId: Int) { + drawer.setContentView(layoutResId) + initAdView(layoutResId) + onContentChanged() + } + /** Called when the activity is first created. */ override def onCreate(savedInstanceState: Bundle) { setHeaderRes(R.xml.shadowsocks_headers) super.onCreate(savedInstanceState) + val menuView = new TextView(this) + menuView.setTextColor(0xFFFFFFFF) + menuView.setText("As the drawer opens, the drawer indicator icon becomes smaller.") + menuView.setGravity(Gravity.CENTER) + drawer.setMenuView(menuView) + + // The drawable that replaces the up indicator in the action bar + drawer.setSlideDrawable(R.drawable.ic_drawer) + // Whether the previous drawable should be shown + drawer.setDrawerIndicatorEnabled(true) + val switchLayout = getLayoutInflater .inflate(R.layout.layout_switch, null) .asInstanceOf[RelativeLayout] getSupportActionBar.setCustomView(switchLayout) getSupportActionBar.setDisplayShowTitleEnabled(false) getSupportActionBar.setDisplayShowCustomEnabled(true) - getSupportActionBar.setDisplayShowHomeEnabled(false) + // getSupportActionBar.setDisplayShowHomeEnabled(false) val title: TextView = switchLayout.findViewById(R.id.title).asInstanceOf[TextView] val tf: Typeface = Typefaces.get(this, "fonts/Iceland.ttf") @@ -402,13 +424,8 @@ class Shadowsocks title.setText(R.string.app_name) switchButton = switchLayout.findViewById(R.id.switchButton).asInstanceOf[Switch] - settings = PreferenceManager.getDefaultSharedPreferences(this) - status = getSharedPreferences(Key.status, Context.MODE_PRIVATE) - receiver = new StateBroadcastReceiver() registerReceiver(receiver, new IntentFilter(Action.UPDATE_STATE)) - initAdView() - val init: Boolean = !Shadowsocks.isServiceStarted(this) if (init) { if (progressDialog == null) { @@ -425,7 +442,7 @@ class Shadowsocks } } - override def onCreateOptionsMenu(menu: Menu): Boolean = { +/* override def onCreateOptionsMenu(menu: Menu): Boolean = { val isRoot = status.getBoolean(Key.isRoot, false) menu .add(0, 0, 0, R.string.recovery) @@ -442,7 +459,7 @@ class Shadowsocks .setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT) } true - } + }*/ override def onKeyDown(keyCode: Int, event: KeyEvent): Boolean = { if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount == 0) { @@ -459,6 +476,11 @@ class Shadowsocks override def onOptionsItemSelected(item: MenuItem): Boolean = { item.getItemId match { + case android.R.id.home => { + EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "home", getVersionName, 0L) + drawer.toggleMenu() + return true + } case 0 => { EasyTracker.getTracker.sendEvent(Shadowsocks.TAG, "reset", getVersionName, 0L) recovery() diff --git a/src/main/scala/com/github/shadowsocks/database/DBHelper.scala b/src/main/scala/com/github/shadowsocks/database/DBHelper.scala new file mode 100644 index 00000000..654c0acb --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/database/DBHelper.scala @@ -0,0 +1,22 @@ +package com.github.shadowsocks.database + +import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import com.j256.ormlite.support.ConnectionSource +import com.j256.ormlite.table.TableUtils +import com.j256.ormlite.dao.Dao + +class DBHelper(implicit val context: Context) extends OrmLiteSqliteOpenHelper(context, "postnauka", null, 3) { + + lazy val profileDao:Dao[Profile,Int] = getDao(classOf[Profile]) + + def onCreate(database: SQLiteDatabase, connectionSource: ConnectionSource) { + TableUtils.createTable(connectionSource, classOf[Profile]) + } + + def onUpgrade(database: SQLiteDatabase, connectionSource: ConnectionSource, oldVersion: Int, newVersion: Int) { + TableUtils.dropTable(connectionSource, classOf[Profile], true) + onCreate(database, connectionSource) + } +} diff --git a/src/main/scala/com/github/shadowsocks/database/Profile.scala b/src/main/scala/com/github/shadowsocks/database/Profile.scala new file mode 100644 index 00000000..b034aab0 --- /dev/null +++ b/src/main/scala/com/github/shadowsocks/database/Profile.scala @@ -0,0 +1,47 @@ +package com.github.shadowsocks.database + +import com.j256.ormlite.field.{DataType, DatabaseField} + +class Profile { + @DatabaseField(id = true) + var id: Int = 0 + + @DatabaseField + var name: String = null + + @DatabaseField(foreign = true, canBeNull = false) + var host: String = null + + @DatabaseField + var localPort: Int = 0 + + @DatabaseField + var remotePort: Int = 0 + + @DatabaseField + var password: String = null + + @DatabaseField + var method: String = null + + @DatabaseField + var date: String = null + + @DatabaseField + var upload: Int = 0 + + @DatabaseField + var download: Int = 0 + + @DatabaseField + var chnroute: Boolean = false + + @DatabaseField + var global: Boolean = false + + @DatabaseField(dataType = DataType.LONG_STRING) + var individual: String = null + + @DatabaseField(dataType = DataType.LONG_STRING) + var description: String = null +}