Use tags from status when adding handlers to hashtag spans in status content (#2344)

* Migrate LinkHelper to kotlin

* Support tags field on statuses

* Use embedded tags list in status instead of text scraping to embed tag click handler.
Fixes #2283

* Make mentions and tags lists nonnullable

* Make LinkHelper.openLink a Context extension method

* Use builtin extension for uri conversion

* More cleanup in LinkHelper

* Add tests for LinkHelper.getDomain

* Unbreak tags in places that don't have a tag list (e.g. profiles)

* Fixup javadoc
This commit is contained in:
Levi Bard 2022-02-25 18:56:21 +01:00 committed by GitHub
commit addce87eb6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1294 additions and 296 deletions

View file

@ -32,7 +32,7 @@ import java.io.File;
@Database(entities = { DraftEntity.class, AccountEntity.class, InstanceEntity.class, TimelineStatusEntity.class,
TimelineAccountEntity.class, ConversationEntity.class
}, version = 28)
}, version = 29)
public abstract class AppDatabase extends RoomDatabase {
public abstract AccountDao accountDao();
@ -457,4 +457,12 @@ public abstract class AppDatabase extends RoomDatabase {
"ON `TimelineStatusEntity` (`authorServerId`, `timelineUserId`)");
}
};
public static final Migration MIGRATION_28_29 = new Migration(28, 29) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE `ConversationEntity` ADD COLUMN `s_tags` TEXT NOT NULL");
database.execSQL("ALTER TABLE `TimelineStatusEntity` ADD COLUMN `tags` TEXT");
}
};
}

View file

@ -27,6 +27,7 @@ import com.keylesspalace.tusky.components.conversation.ConversationAccountEntity
import com.keylesspalace.tusky.createTabDataFromId
import com.keylesspalace.tusky.entity.Attachment
import com.keylesspalace.tusky.entity.Emoji
import com.keylesspalace.tusky.entity.HashTag
import com.keylesspalace.tusky.entity.NewPoll
import com.keylesspalace.tusky.entity.Poll
import com.keylesspalace.tusky.entity.Status
@ -119,6 +120,16 @@ class Converters @Inject constructor (
return gson.fromJson(mentionListJson, object : TypeToken<List<Status.Mention>>() {}.type)
}
@TypeConverter
fun tagListToJson(tagArray: List<HashTag>?): String? {
return gson.toJson(tagArray)
}
@TypeConverter
fun jsonToTagArray(tagListJson: String?): List<HashTag>? {
return gson.fromJson(tagListJson, object : TypeToken<List<HashTag>>() {}.type)
}
@TypeConverter
fun dateToLong(date: Date): Long {
return date.time

View file

@ -35,7 +35,7 @@ abstract class TimelineDao {
SELECT s.serverId, s.url, s.timelineUserId,
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt,
s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
s.spoilerText, s.visibility, s.mentions, s.application, s.reblogServerId,s.reblogAccountId,
s.spoilerText, s.visibility, s.mentions, s.tags, s.application, s.reblogServerId,s.reblogAccountId,
s.content, s.attachments, s.poll, s.muted, s.expanded, s.contentShowing, s.contentCollapsed, s.pinned,
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
a.localUsername as 'a_localUsername', a.username as 'a_username',

View file

@ -69,6 +69,7 @@ data class TimelineStatusEntity(
val visibility: Status.Visibility,
val attachments: String?,
val mentions: String?,
val tags: String?,
val application: String?,
val reblogServerId: String?, // if it has a reblogged status, it's id is stored here
val reblogAccountId: String?,