1
0
mirror of https://github.com/chylex/Discord-History-Tracker.git synced 2024-11-25 05:42:45 +01:00

Compare commits

..

3 Commits

16 changed files with 50 additions and 26 deletions

View File

@ -249,11 +249,8 @@ sealed partial class MessageFilterPanelModel : ObservableObject, IDisposable {
var checkBoxItems = new List<CheckBoxItem<ulong>>();
await foreach (var user in state.Db.Users.Get()) {
var name = user.Name;
var discriminator = user.Discriminator;
checkBoxItems.Add(new CheckBoxItem<ulong>(user.Id) {
Title = discriminator == null ? name : name + " #" + discriminator,
Title = user.DisplayName == null ? user.Name : $"{user.DisplayName} ({user.Name})",
IsChecked = IncludedUsers == null || IncludedUsers.Contains(user.Id)
});
}

View File

@ -73,6 +73,7 @@ sealed class DebugPageModel {
var users = Enumerable.Range(0, userCount).Select(_ => new User {
Id = RandomId(rand),
Name = RandomName("u"),
DisplayName = RandomName("u"),
AvatarUrl = null,
Discriminator = rand.Next(0, 9999).ToString(),
}).ToArray();

View File

@ -9,6 +9,8 @@ items:
pattern: "^[0-9]+$"
name:
type: string
displayName:
type: string
avatar:
type: string
discriminator:

View File

@ -69,6 +69,7 @@ const STATE = (function() {
* @property {String} id
* @property {String} username
* @property {String} discriminator
* @property {String} [globalName]
* @property {String} [avatar]
* @property {Boolean} [bot]
*/
@ -200,6 +201,10 @@ const STATE = (function() {
name: user.username
};
if (user.globalName) {
obj.displayName = user.globalName;
}
if (user.avatar) {
obj.avatar = user.avatar;
}

View File

@ -80,7 +80,7 @@ export default (function() {
processed = processed
.replace(regex.formatUrl, "<a href='$1' target='_blank' rel='noreferrer'>$1</a>")
.replace(regex.mentionChannel, (full, match) => "<span class='link mention-chat'>#" + state.getChannelName(match) + "</span>")
.replace(regex.mentionUser, (full, match) => "<span class='link mention-user' title='#" + (state.getUserTag(match) || "????") + "'>@" + state.getUserName(match) + "</span>")
.replace(regex.mentionUser, (full, match) => "<span class='link mention-user' title='" + state.getUserName(match) + "'>@" + state.getUserDisplayName(match) + "</span>")
.replace(regex.customEmojiStatic, (full, m1, m2) => getEmoji(m1, m2, "webp"))
.replace(regex.customEmojiAnimated, (full, m1, m2) => getEmoji(m1, m2, animatedEmojiExtension));
@ -129,7 +129,7 @@ export default (function() {
templateMessageNoAvatar = new template([
"<div>",
"<div class='reply-message'>{reply}</div>",
"<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
"<h2><strong class='username' title='{user.name}'>{user.displayName}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
"<div class='message'>{contents}{embeds}{attachments}</div>",
"{reactions}",
"</div>"
@ -141,7 +141,7 @@ export default (function() {
"<div class='avatar-wrapper'>",
"<div class='avatar'>{avatar}</div>",
"<div>",
"<h2><strong class='username' title='#{user.tag}'>{user.name}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
"<h2><strong class='username' title='{user.name}'>{user.displayName}</strong><span class='info time'>{timestamp}</span>{edit}{jump}</h2>",
"<div class='message'>{contents}{embeds}{attachments}</div>",
"{reactions}",
"</div>",
@ -227,8 +227,8 @@ export default (function() {
if (property === "avatar") {
return value ? templateUserAvatar.apply(getAvatarUrlObject(value)) : "";
}
else if (property === "user.tag") {
return value ? value : "????";
else if (property === "user.displayName") {
return value ? value : message.user.name;
}
else if (property === "timestamp") {
return dom.getHumanReadableTime(value);
@ -292,7 +292,7 @@ export default (function() {
return value === null ? "<span class='reply-contents reply-missing'>(replies to an unknown message)</span>" : "";
}
const user = "<span class='reply-username' title='#" + (value.user.tag ? value.user.tag : "????") + "'>" + value.user.name + "</span>";
const user = "<span class='reply-username' title='" + value.user.name + "'>" + (value.user.displayName ?? value.user.name) + "</span>";
const avatar = settings.enableUserAvatars && value.avatar ? "<span class='reply-avatar'>" + templateUserAvatar.apply(getAvatarUrlObject(value.avatar)) + "</span>" : "";
const contents = value.contents ? "<span class='reply-contents'>" + processMessageContents(value.contents) + "</span>" : "";

View File

@ -243,10 +243,11 @@ export default (function() {
const options = [];
for (const key of Object.keys(users)) {
for (const id of Object.keys(users)) {
const user = users[id];
const option = document.createElement("option");
option.value = key;
option.text = users[key].name;
option.value = id;
option.text = user.displayName ? `${user.displayName} (${user.name})` : user.name;
options.push(option);
}

View File

@ -316,16 +316,16 @@ export default (function() {
return (channelObj && channelObj.name) || channel;
},
getUserTag(user) {
const userObj = loadedFileMeta.users[user];
return (userObj && userObj.tag) || "????";
},
getUserName(user) {
const userObj = loadedFileMeta.users[user];
return (userObj && userObj.name) || user;
},
getUserDisplayName(user) {
const userObj = loadedFileMeta.users[user];
return (userObj && (userObj.displayName || userObj.name)) || user;
},
selectChannel(channel) {
currentPage = 1;
selectedChannel = channel;

View File

@ -3,6 +3,7 @@ namespace DHT.Server.Data;
public readonly struct User {
public ulong Id { get; init; }
public string Name { get; init; }
public string? DisplayName { get; init; }
public string? AvatarUrl { get; init; }
public string? Discriminator { get; init; }
}

View File

@ -14,10 +14,10 @@ static class ViewerJson {
public required string Name { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Avatar { get; init; }
public string? DisplayName { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Tag { get; init; }
public string? Avatar { get; init; }
}
public sealed class JsonServer {

View File

@ -68,8 +68,8 @@ static class ViewerJsonExport {
await foreach (var user in db.Users.Get(cancellationToken)) {
users[user.Id] = new ViewerJson.JsonUser {
Name = user.Name,
DisplayName = user.DisplayName,
Avatar = user.AvatarUrl,
Tag = user.Discriminator
};
}

View File

@ -29,6 +29,7 @@ sealed class SqliteUserRepository : BaseSqliteRepository, IUserRepository {
await using var cmd = conn.Upsert("users", [
("id", SqliteType.Integer),
("name", SqliteType.Text),
("display_name", SqliteType.Text),
("avatar_url", SqliteType.Text),
("discriminator", SqliteType.Text)
]);
@ -38,6 +39,7 @@ sealed class SqliteUserRepository : BaseSqliteRepository, IUserRepository {
foreach (var user in users) {
cmd.Set(":id", user.Id);
cmd.Set(":name", user.Name);
cmd.Set(":display_name", user.DisplayName);
cmd.Set(":avatar_url", user.AvatarUrl);
cmd.Set(":discriminator", user.Discriminator);
await cmd.ExecuteNonQueryAsync();
@ -62,15 +64,16 @@ sealed class SqliteUserRepository : BaseSqliteRepository, IUserRepository {
public async IAsyncEnumerable<User> Get([EnumeratorCancellation] CancellationToken cancellationToken) {
await using var conn = await pool.Take();
await using var cmd = conn.Command("SELECT id, name, avatar_url, discriminator FROM users");
await using var cmd = conn.Command("SELECT id, name, display_name, avatar_url, discriminator FROM users");
await using var reader = await cmd.ExecuteReaderAsync(cancellationToken);
while (await reader.ReadAsync(cancellationToken)) {
yield return new User {
Id = reader.GetUint64(0),
Name = reader.GetString(1),
AvatarUrl = reader.IsDBNull(2) ? null : reader.GetString(2),
Discriminator = reader.IsDBNull(3) ? null : reader.GetString(3),
DisplayName = reader.IsDBNull(2) ? null : reader.GetString(2),
AvatarUrl = reader.IsDBNull(3) ? null : reader.GetString(3),
Discriminator = reader.IsDBNull(4) ? null : reader.GetString(4),
};
}
}

View File

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using DHT.Server.Database.Sqlite.Utils;
namespace DHT.Server.Database.Sqlite.Schema;
sealed class SqliteSchemaUpgradeTo8 : ISchemaUpgrade {
async Task ISchemaUpgrade.Run(ISqliteConnection conn, ISchemaUpgradeCallbacks.IProgressReporter reporter) {
await reporter.MainWork("Applying schema changes...", 0, 1);
await conn.ExecuteAsync("ALTER TABLE users ADD display_name TEXT");
}
}

View File

@ -8,7 +8,7 @@ using DHT.Utils.Logging;
namespace DHT.Server.Database.Sqlite;
sealed class SqliteSchema {
internal const int Version = 7;
internal const int Version = 8;
private static readonly Log Log = Log.ForType<SqliteSchema>();
@ -48,6 +48,7 @@ sealed class SqliteSchema {
CREATE TABLE users (
id INTEGER PRIMARY KEY NOT NULL,
name TEXT NOT NULL,
display_name TEXT,
avatar_url TEXT,
discriminator TEXT
)
@ -171,6 +172,7 @@ sealed class SqliteSchema {
{ 4, new SqliteSchemaUpgradeTo5() },
{ 5, new SqliteSchemaUpgradeTo6() },
{ 6, new SqliteSchemaUpgradeTo7() },
{ 7, new SqliteSchemaUpgradeTo8() },
};
var perf = Log.Start("from version " + dbVersion);

View File

@ -30,6 +30,7 @@ sealed class TrackUsersEndpoint(IDatabaseFile db) : BaseEndpoint(db) {
private static User ReadUser(JsonElement json, string path) => new () {
Id = json.RequireSnowflake("id", path),
Name = json.RequireString("name", path),
DisplayName = json.HasKey("displayName") ? json.RequireString("displayName", path) : null,
AvatarUrl = json.HasKey("avatar") ? json.RequireString("avatar", path) : null,
Discriminator = json.HasKey("discriminator") ? json.RequireString("discriminator", path) : null
};

View File

@ -8,5 +8,5 @@ using DHT.Utils;
namespace DHT.Utils;
static class Version {
public const string Tag = "42.0.0.0";
public const string Tag = "42.1.0.0";
}

Binary file not shown.