From 164becfed08bdb673df247c5d79a492153dbe118 Mon Sep 17 00:00:00 2001 From: Mygod Date: Fri, 25 Dec 2015 15:51:18 +0800 Subject: [PATCH] Implement dragging to move profiles --- .../shadowsocks/ProfileManagerActivity.scala | 26 +++++++++++++++++-- .../com/github/shadowsocks/Shadowsocks.scala | 7 ++--- .../shadowsocks/database/DBHelper.scala | 11 +++++++- .../github/shadowsocks/database/Profile.scala | 3 +++ .../shadowsocks/database/ProfileManager.scala | 15 ++++++++++- 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala b/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala index 4d2fdb17..2bf39cc5 100644 --- a/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala +++ b/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala @@ -111,6 +111,24 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe notifyItemInserted(pos) } + def move(from: Int, to: Int) { + val step = if (from < to) 1 else -1 + val first = profiles(from) + var previousOrder = profiles(from).userOrder + for (i <- from until to by step) { + val next = profiles(i + step) + val order = next.userOrder + next.userOrder = previousOrder + previousOrder = order + profiles(i) = next + ShadowsocksApplication.profileManager.updateProfile(next) + } + first.userOrder = previousOrder + profiles(to) = first + ShadowsocksApplication.profileManager.updateProfile(first) + notifyItemMoved(from, to) + } + def remove(pos: Int) { recycleBin.append((pos, profiles(pos))) profiles.remove(pos) @@ -169,12 +187,16 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe def onViewDetachedFromWindow(v: View) = profilesAdapter.commitRemoves def onViewAttachedToWindow(v: View) = () }) - new ItemTouchHelper(new SimpleCallback(0, ItemTouchHelper.START | ItemTouchHelper.END) { + new ItemTouchHelper(new SimpleCallback(ItemTouchHelper.UP | ItemTouchHelper.DOWN, + ItemTouchHelper.START | ItemTouchHelper.END) { def onSwiped(viewHolder: ViewHolder, direction: Int) = { profilesAdapter.remove(viewHolder.getAdapterPosition) removedSnackbar.show } - def onMove(recyclerView: RecyclerView, viewHolder: ViewHolder, target: ViewHolder) = false // TODO? + def onMove(recyclerView: RecyclerView, viewHolder: ViewHolder, target: ViewHolder) = { + profilesAdapter.move(viewHolder.getAdapterPosition, target.getAdapterPosition) + true + } }).attachToRecyclerView(profilesList) attachService(new IShadowsocksServiceCallback.Stub { diff --git a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala index 5f3391ac..5a61774f 100644 --- a/src/main/scala/com/github/shadowsocks/Shadowsocks.scala +++ b/src/main/scala/com/github/shadowsocks/Shadowsocks.scala @@ -438,9 +438,10 @@ class Shadowsocks currentProfile = ShadowsocksApplication.currentProfile match { case Some(profile) => profile // updated case None => // removed - val profiles = ShadowsocksApplication.profileManager.getAllProfiles.getOrElse(List[Profile]()) - if (profiles.isEmpty) ShadowsocksApplication.profileManager.createDefault() - else ShadowsocksApplication.switchProfile(profiles.head.id) + ShadowsocksApplication.profileManager.getFirstProfile match { + case Some(first) => ShadowsocksApplication.switchProfile(first.id) + case None => ShadowsocksApplication.profileManager.createDefault() + } } updatePreferenceScreen() diff --git a/src/main/scala/com/github/shadowsocks/database/DBHelper.scala b/src/main/scala/com/github/shadowsocks/database/DBHelper.scala index aee1fe9f..afd64535 100644 --- a/src/main/scala/com/github/shadowsocks/database/DBHelper.scala +++ b/src/main/scala/com/github/shadowsocks/database/DBHelper.scala @@ -64,7 +64,7 @@ object DBHelper { } class DBHelper(val context: Context) - extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 14) { + extends OrmLiteSqliteOpenHelper(context, DBHelper.PROFILE, null, 15) { import DBHelper._ lazy val profileDao: Dao[Profile, Int] = getDao(classOf[Profile]) @@ -116,6 +116,15 @@ class DBHelper(val context: Context) profileDao.update(profile) } } + if (oldVersion < 15) { + profileDao.executeRawNoArgs("ALTER TABLE `profile` ADD COLUMN userOrder LONG;") + var i = 0 + for (profile <- profileDao.queryForAll.asScala) { + profile.userOrder = i + profileDao.update(profile) + i += 1 + } + } } } } diff --git a/src/main/scala/com/github/shadowsocks/database/Profile.scala b/src/main/scala/com/github/shadowsocks/database/Profile.scala index 66744357..4f3c7917 100644 --- a/src/main/scala/com/github/shadowsocks/database/Profile.scala +++ b/src/main/scala/com/github/shadowsocks/database/Profile.scala @@ -92,4 +92,7 @@ class Profile { @DatabaseField val date: java.util.Date = new java.util.Date() + + @DatabaseField + var userOrder: Long = _ } diff --git a/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala b/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala index 0cf4d8e5..50cae234 100644 --- a/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala +++ b/src/main/scala/com/github/shadowsocks/database/ProfileManager.scala @@ -64,6 +64,9 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) { profile.udpdns = oldProfile.udpdns case _ => } + val last = dbHelper.profileDao.queryRaw(dbHelper.profileDao.queryBuilder.selectRaw("MAX(userOrder)") + .prepareStatementString).getFirstResult + if (last != null && last.length == 1) profile.userOrder = last(0).toInt + 1 dbHelper.profileDao.createOrUpdate(profile) if (profileAddedListener != null) profileAddedListener(profile) profile @@ -109,10 +112,20 @@ class ProfileManager(settings: SharedPreferences, dbHelper: DBHelper) { } } + def getFirstProfile = { + try { + Option(dbHelper.profileDao.query(dbHelper.profileDao.queryBuilder.limit(1L).prepare).get(0)) + } catch { + case ex: Exception => + Log.e(Shadowsocks.TAG, "getAllProfiles", ex) + None + } + } + def getAllProfiles: Option[List[Profile]] = { try { import scala.collection.JavaConversions._ - Option(dbHelper.profileDao.queryForAll().toList) + Option(dbHelper.profileDao.query(dbHelper.profileDao.queryBuilder.orderBy("userOrder", true).prepare).toList) } catch { case ex: Exception => Log.e(Shadowsocks.TAG, "getAllProfiles", ex)