Search: introduce weighted reordering (#272)

* Database: backend for weights & timestamps

- Migration 21->22
- SearchableLaunchTimestampEntity.kt
- `weight`-column in SavedSearchableEntity
- Queries for sorting by and adjusting weight
- Queries for sorting by recent use

* move weightfactor access to favoritesRepository

* reorder calls in SearchVM

* no more datahoarding

* add settings screen for ordering

* ui fix, animations

* move ordering settings out of own screen

* remove unused localization

* weight factors

* larger factor for WeightFactor.High

* cleanup

* sort favorites by weight

* icons for favorite screen

* I hate coming up with descriptive strings

* add default weight factor to settings migration

* Add default values for search result ordering preferences

* Favorites settings: change order of preferences

* Change strings

* Replace favorites variability slider with list preference

* migration initial weight

* Change labels

* Include searchable weight column in backup

---------

Co-authored-by: MM20 <15646950+MM2-0@users.noreply.github.com>
This commit is contained in:
Christoph
2023-03-10 22:17:03 +01:00
committed by GitHub
co-authored by MM20
parent 003789f310
commit 2c9cba72a9
21 changed files with 838 additions and 163 deletions
@@ -0,0 +1,499 @@
{
"formatVersion": 1,
"database": {
"version": 22,
"identityHash": "5d3853b609231cdcab5fb3c681d05ebb",
"entities": [
{
"tableName": "forecasts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`timestamp` INTEGER NOT NULL, `temperature` REAL NOT NULL, `minTemp` REAL NOT NULL, `maxTemp` REAL NOT NULL, `pressure` REAL NOT NULL, `humidity` REAL NOT NULL, `icon` INTEGER NOT NULL, `condition` TEXT NOT NULL, `clouds` INTEGER NOT NULL, `windSpeed` REAL NOT NULL, `windDirection` REAL NOT NULL, `rain` REAL NOT NULL, `snow` REAL NOT NULL, `night` INTEGER NOT NULL, `location` TEXT NOT NULL, `provider` TEXT NOT NULL, `providerUrl` TEXT NOT NULL, `rainProbability` INTEGER NOT NULL, `snowProbability` INTEGER NOT NULL, `updateTime` INTEGER NOT NULL, PRIMARY KEY(`timestamp`))",
"fields": [
{
"fieldPath": "timestamp",
"columnName": "timestamp",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "temperature",
"columnName": "temperature",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "minTemp",
"columnName": "minTemp",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "maxTemp",
"columnName": "maxTemp",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "pressure",
"columnName": "pressure",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "humidity",
"columnName": "humidity",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "condition",
"columnName": "condition",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "clouds",
"columnName": "clouds",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "windSpeed",
"columnName": "windSpeed",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "windDirection",
"columnName": "windDirection",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "precipitation",
"columnName": "rain",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "snow",
"columnName": "snow",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "night",
"columnName": "night",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "location",
"columnName": "location",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "provider",
"columnName": "provider",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "providerUrl",
"columnName": "providerUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "precipProbability",
"columnName": "rainProbability",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "snowProbability",
"columnName": "snowProbability",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "updateTime",
"columnName": "updateTime",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"timestamp"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Searchable",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `type` TEXT NOT NULL, `searchable` TEXT NOT NULL, `launchCount` INTEGER NOT NULL, `pinned` INTEGER NOT NULL, `hidden` INTEGER NOT NULL, `weight` REAL NOT NULL DEFAULT 0.0, PRIMARY KEY(`key`))",
"fields": [
{
"fieldPath": "key",
"columnName": "key",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "serializedSearchable",
"columnName": "searchable",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "launchCount",
"columnName": "launchCount",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "pinPosition",
"columnName": "pinned",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "hidden",
"columnName": "hidden",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "weight",
"columnName": "weight",
"affinity": "REAL",
"notNull": true,
"defaultValue": "0.0"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"key"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Currency",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`symbol` TEXT NOT NULL, `value` REAL NOT NULL, `lastUpdate` INTEGER NOT NULL, PRIMARY KEY(`symbol`))",
"fields": [
{
"fieldPath": "symbol",
"columnName": "symbol",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "lastUpdate",
"columnName": "lastUpdate",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"symbol"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Icons",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` TEXT NOT NULL, `packageName` TEXT, `activityName` TEXT, `drawable` TEXT, `extras` TEXT, `iconPack` TEXT NOT NULL, `name` TEXT, `themed` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
"fields": [
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "packageName",
"columnName": "packageName",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "activityName",
"columnName": "activityName",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "drawable",
"columnName": "drawable",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "extras",
"columnName": "extras",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "iconPack",
"columnName": "iconPack",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "themed",
"columnName": "themed",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "IconPack",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`name` TEXT NOT NULL, `packageName` TEXT NOT NULL, `version` TEXT NOT NULL, `scale` REAL NOT NULL, `themed` INTEGER NOT NULL, PRIMARY KEY(`packageName`))",
"fields": [
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "packageName",
"columnName": "packageName",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "version",
"columnName": "version",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "scale",
"columnName": "scale",
"affinity": "REAL",
"notNull": true
},
{
"fieldPath": "themed",
"columnName": "themed",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"packageName"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "Widget",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` TEXT NOT NULL, `data` TEXT NOT NULL, `height` INTEGER NOT NULL, `position` INTEGER NOT NULL, `label` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
"fields": [
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "data",
"columnName": "data",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "height",
"columnName": "height",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "position",
"columnName": "position",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "label",
"columnName": "label",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "CustomAttributes",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `type` TEXT NOT NULL, `value` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT)",
"fields": [
{
"fieldPath": "key",
"columnName": "key",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "value",
"columnName": "value",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "SearchAction",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`position` INTEGER NOT NULL, `type` TEXT NOT NULL, `data` TEXT, `label` TEXT, `icon` INTEGER, `color` INTEGER, `customIcon` TEXT, `options` TEXT, PRIMARY KEY(`position`))",
"fields": [
{
"fieldPath": "position",
"columnName": "position",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "data",
"columnName": "data",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "label",
"columnName": "label",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "customIcon",
"columnName": "customIcon",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "options",
"columnName": "options",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"position"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '5d3853b609231cdcab5fb3c681d05ebb')"
]
}
}
@@ -7,7 +7,6 @@ import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import de.mm20.launcher2.database.entities.*
import de.mm20.launcher2.database.migrations.Migration_10_11
@@ -21,6 +20,7 @@ import de.mm20.launcher2.database.migrations.Migration_17_18
import de.mm20.launcher2.database.migrations.Migration_18_19
import de.mm20.launcher2.database.migrations.Migration_19_20
import de.mm20.launcher2.database.migrations.Migration_20_21
import de.mm20.launcher2.database.migrations.Migration_21_22
import de.mm20.launcher2.database.migrations.Migration_6_7
import de.mm20.launcher2.database.migrations.Migration_7_8
import de.mm20.launcher2.database.migrations.Migration_8_9
@@ -35,8 +35,8 @@ import de.mm20.launcher2.database.migrations.Migration_9_10
IconPackEntity::class,
WidgetEntity::class,
CustomAttributeEntity::class,
SearchActionEntity::class,
], version = 21, exportSchema = true
SearchActionEntity::class
], version = 22, exportSchema = true
)
@TypeConverters(ComponentNameConverter::class, StringListConverter::class)
abstract class AppDatabase : RoomDatabase() {
@@ -104,6 +104,7 @@ abstract class AppDatabase : RoomDatabase() {
Migration_18_19(),
Migration_19_20(),
Migration_20_21(),
Migration_21_22()
).build()
if (_instance == null) _instance = instance
return instance
@@ -7,7 +7,7 @@ import kotlinx.coroutines.flow.Flow
@Dao
interface SearchDao {
@Insert()
@Insert
fun insertAll(items: List<SavedSearchableEntity>)
@Insert(onConflict = OnConflictStrategy.IGNORE)
@@ -19,12 +19,13 @@ interface SearchDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAllReplaceExisting(items: List<SavedSearchableEntity>)
@Query("SELECT * FROM Searchable " +
"WHERE ((:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
@Query(
"SELECT * FROM Searchable " +
"WHERE ((:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, weight DESC, launchCount DESC LIMIT :limit"
)
fun getFavorites(
manuallySorted: Boolean = false,
automaticallySorted: Boolean = false,
@@ -32,12 +33,14 @@ interface SearchDao {
limit: Int,
): Flow<List<SavedSearchableEntity>>
@Query("SELECT * FROM Searchable " +
"WHERE SUBSTR(`key`, 0, INSTR(`key`, '://')) IN (:includeTypes) AND (" +
"(:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
@Query(
"SELECT * FROM Searchable " +
"WHERE SUBSTR(`key`, 0, INSTR(`key`, '://')) IN (:includeTypes) AND (" +
"(:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, weight DESC, launchCount DESC LIMIT :limit"
)
fun getFavoritesWithTypes(
includeTypes: List<String>,
manuallySorted: Boolean = false,
@@ -46,12 +49,14 @@ interface SearchDao {
limit: Int,
): Flow<List<SavedSearchableEntity>>
@Query("SELECT * FROM Searchable " +
"WHERE `type` NOT IN (:excludeTypes) AND (" +
"(:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, launchCount DESC LIMIT :limit")
@Query(
"SELECT * FROM Searchable " +
"WHERE `type` NOT IN (:excludeTypes) AND (" +
"(:manuallySorted AND pinned > 1) OR " +
"(:automaticallySorted AND pinned = 1) OR" +
"(:frequentlyUsed AND pinned = 0 AND launchCount > 0)" +
") ORDER BY pinned DESC, weight DESC, launchCount DESC LIMIT :limit"
)
fun getFavoritesWithoutTypes(
excludeTypes: List<String>,
manuallySorted: Boolean = false,
@@ -114,8 +119,10 @@ interface SearchDao {
fun incrementExistingLaunchCount(key: String)
@Transaction
fun incrementLaunchCount(item: SavedSearchableEntity) {
fun incrementLaunchCount(item: SavedSearchableEntity, alpha: Double) {
incrementExistingLaunchCount(item.key)
increaseWeightWhere(item.key, alpha)
reduceWeightExcept(item.key, alpha)
insertSkipExisting(item)
}
@@ -140,9 +147,18 @@ interface SearchDao {
@Query("UPDATE Searchable SET `pinned` = 0")
fun unpinAll()
@Query("UPDATE Searchable Set `pinned` = 0, `launchCount` = 0 WHERE `key` = :key")
@Query("UPDATE Searchable SET `pinned` = 0, `launchCount` = 0 WHERE `key` = :key")
suspend fun resetPinStatusAndLaunchCounter(key: String)
@Query("SELECT `key` FROM Searchable WHERE `key` IN (:keys) AND launchCount > 0 ORDER BY launchCount DESC, pinned DESC")
fun sortByRelevance(keys: List<String>): Flow<List<String>>
@Query("SELECT `key` FROM Searchable WHERE `key` IN (:keys) ORDER BY `weight` DESC, pinned DESC")
fun sortByWeight(keys: List<String>): Flow<List<String>>
@Query("UPDATE Searchable SET `weight` = `weight` * (1.0 - :alpha) WHERE `key` != :key")
fun reduceWeightExcept(key: String, alpha: Double)
@Query("UPDATE Searchable SET `weight` = `weight` + :alpha * (1.0 - `weight`) WHERE `key` == :key")
fun increaseWeightWhere(key: String, alpha: Double)
}
@@ -11,5 +11,6 @@ data class SavedSearchableEntity(
@ColumnInfo(name = "searchable") val serializedSearchable: String,
var launchCount: Int,
@ColumnInfo(name = "pinned") var pinPosition: Int,
var hidden: Boolean
var hidden: Boolean,
@ColumnInfo(defaultValue = "0.0") var weight: Double
)
@@ -0,0 +1,37 @@
package de.mm20.launcher2.database.migrations
import android.util.Log
import androidx.core.database.getIntOrNull
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration_21_22: Migration(21, 22) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
ALTER TABLE `Searchable`
ADD `weight` DOUBLE NOT NULL DEFAULT 0.0
""")
database.query("""
SELECT MAX(`launchCount`)
FROM `Searchable`
""")
.runCatching {
if (!this.moveToFirst()) {
return
}
this.getIntOrNull(0)
?.run {
database.execSQL("""
UPDATE `Searchable`
SET `weight` = `launchCount` / $this
""")
}
}.onFailure {
Log.e("Migration_21_22", "Setting default values for weight failed", it)
}
}
}
+8 -3
View File
@@ -574,7 +574,12 @@
<string name="preference_layout_fixed_rotation">Feste Bildschirmausrichtung</string>
<string name="preference_layout_fixed_rotation_summary">Porträtmodus erzwingen</string>
<string name="icon_pack_dynamic_colors">Dynamische Farben</string>
<string name="preference_search_bar_ordering">Anordnung der Suchergebnisse</string>
<string name="preference_search_bar_ordering_alphabetic">Alphabetisch</string>
<string name="preference_search_bar_ordering_relevance">Relevanz</string>
<string name="preference_search_result_ordering">Sortierung der Suchergebnisse</string>
<string name="preference_search_result_ordering_alphabetic">Alphabetisch</string>
<string name="preference_search_result_ordering_launch_count">Aufrufhäufigkeit</string>
<string name="preference_search_result_ordering_weighted">Dynamisch</string>
<string name="preference_search_result_ordering_weight_factor">Ranking-Flexibilität</string>
<string name="preference_search_result_ordering_weight_factor_low">Stabil</string>
<string name="preference_search_result_ordering_weight_factor_default">Ausgewogen</string>
<string name="preference_search_result_ordering_weight_factor_high">Variabel</string>
</resources>
+8 -3
View File
@@ -761,7 +761,12 @@
<string name="gesture_failed_message">You have performed a \"%1$s\" gesture. This gesture is currently set to trigger a \"%2$s\" action. However, the action could not be performed for the following reason:</string>
<string name="missing_permission_accessibility_gesture_failed">The launcher\'s accessibility service needs to be enabled to perform this action.</string>
<string name="missing_permission_accessibility_gesture_settings">This action requires the launcher\'s accessibility service to be enabled.</string>
<string name="preference_search_bar_ordering">Search-result order</string>
<string name="preference_search_bar_ordering_alphabetic">Alphabetic</string>
<string name="preference_search_bar_ordering_relevance">Relevance</string>
<string name="preference_search_result_ordering">Order of search results</string>
<string name="preference_search_result_ordering_alphabetic">Alphabetic</string>
<string name="preference_search_result_ordering_launch_count">Launch count</string>
<string name="preference_search_result_ordering_weighted">Dynamic</string>
<string name="preference_search_result_ordering_weight_factor">Ranking flexibility</string>
<string name="preference_search_result_ordering_weight_factor_low">Stable</string>
<string name="preference_search_result_ordering_weight_factor_default">Balanced</string>
<string name="preference_search_result_ordering_weight_factor_high">Variable</string>
</resources>
@@ -183,6 +183,11 @@ fun createFactorySettings(context: Context): Settings {
.setSwipeLeft(Settings.GestureSettings.GestureAction.None)
.setSwipeRight(Settings.GestureSettings.GestureAction.None)
)
.setResultOrdering(
Settings.SearchResultOrderingSettings.newBuilder()
.setOrdering(Settings.SearchResultOrderingSettings.Ordering.Weighted)
.setWeightFactor(Settings.SearchResultOrderingSettings.WeightFactor.Default)
)
.build()
}
@@ -1,6 +1,7 @@
package de.mm20.launcher2.preferences.migrations
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.SearchResultOrderingSettings.WeightFactor
class Migration_12_13: VersionedMigration(12, 13) {
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
@@ -10,5 +11,10 @@ class Migration_12_13: VersionedMigration(12, 13) {
.setDatePart(true)
.build()
)
.setResultOrdering(
builder.resultOrdering.toBuilder()
.setWeightFactor(WeightFactor.Default)
.build()
)
}
}
+16 -5
View File
@@ -223,11 +223,6 @@ message Settings {
}
SearchBarColors color = 3;
bool launch_on_enter = 4;
enum SearchResultOrdering {
Alphabetic = 0;
Relevance = 1;
}
SearchResultOrdering search_result_ordering = 5;
}
SearchBarSettings search_bar = 20;
@@ -332,4 +327,20 @@ message Settings {
string long_press_app = 10;
}
GestureSettings gestures = 28;
message SearchResultOrderingSettings {
enum Ordering {
Alphabetic = 0;
LaunchCount = 1;
Weighted = 2;
}
Ordering ordering = 1;
enum WeightFactor {
Low = 0;
Default = 1;
High = 2;
}
WeightFactor weight_factor = 2;
}
SearchResultOrderingSettings result_ordering = 29;
}