diff --git a/osu.Android.props b/osu.Android.props
index fde58ec489..f3838644d1 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -54,6 +54,6 @@
-
+
diff --git a/osu.Desktop/DiscordRichPresence.cs b/osu.Desktop/DiscordRichPresence.cs
index 80bb82c769..08cc0e7f5f 100644
--- a/osu.Desktop/DiscordRichPresence.cs
+++ b/osu.Desktop/DiscordRichPresence.cs
@@ -75,6 +75,9 @@ namespace osu.Desktop
private void updateStatus()
{
+ if (!client.IsInitialized)
+ return;
+
if (status.Value is UserStatusOffline)
{
client.ClearPresence();
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
index ee2cec1bbd..90e78c3899 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
@@ -18,8 +18,6 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{
public class ColumnHitObjectArea : CompositeDrawable, IHasAccentColour
{
- private const float hit_target_bar_height = 2;
-
private readonly IBindable direction = new Bindable();
private readonly Drawable hitTarget;
@@ -67,6 +65,8 @@ namespace osu.Game.Rulesets.Mania.UI.Components
private class DefaultHitTarget : CompositeDrawable, IHasAccentColour
{
+ private const float hit_target_bar_height = 2;
+
private readonly IBindable direction = new Bindable();
private readonly Container hitTargetLine;
diff --git a/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs
new file mode 100644
index 0000000000..95a5d0acbd
--- /dev/null
+++ b/osu.Game/Online/API/Requests/MarkChannelAsReadRequest.cs
@@ -0,0 +1,30 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Net.Http;
+using osu.Framework.IO.Network;
+using osu.Game.Online.Chat;
+
+namespace osu.Game.Online.API.Requests
+{
+ public class MarkChannelAsReadRequest : APIRequest
+ {
+ private readonly Channel channel;
+ private readonly Message message;
+
+ public MarkChannelAsReadRequest(Channel channel, Message message)
+ {
+ this.channel = channel;
+ this.message = message;
+ }
+
+ protected override string Target => $"chat/channels/{channel.Id}/mark-as-read/{message.Id}";
+
+ protected override WebRequest CreateWebRequest()
+ {
+ var req = base.CreateWebRequest();
+ req.Method = HttpMethod.Put;
+ return req;
+ }
+ }
+}
diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs
index 451174a73c..6f67a95f53 100644
--- a/osu.Game/Online/Chat/Channel.cs
+++ b/osu.Game/Online/Chat/Channel.cs
@@ -36,6 +36,11 @@ namespace osu.Game.Online.Chat
///
public readonly SortedList Messages = new SortedList(Comparer.Default);
+ ///
+ /// Contains all the messages that weren't read by the user.
+ ///
+ public IEnumerable UnreadMessages => Messages.Where(m => LastReadId < m.Id);
+
///
/// Contains all the messages that are still pending for submission to the server.
///
@@ -75,6 +80,9 @@ namespace osu.Game.Online.Chat
[JsonProperty(@"last_message_id")]
public long? LastMessageId;
+ [JsonProperty(@"last_read_id")]
+ public long? LastReadId;
+
///
/// Signalles if the current user joined this channel or not. Defaults to false.
///
diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs
index 1d8c5609d9..4b5ec1cad0 100644
--- a/osu.Game/Online/Chat/ChannelManager.cs
+++ b/osu.Game/Online/Chat/ChannelManager.cs
@@ -445,6 +445,28 @@ namespace osu.Game.Online.Chat
return tcs.Task;
}
+ ///
+ /// Marks the as read
+ ///
+ /// The channel that will be marked as read
+ public void MarkChannelAsRead(Channel channel)
+ {
+ if (channel.LastMessageId == channel.LastReadId)
+ return;
+
+ var message = channel.Messages.LastOrDefault();
+
+ if (message == null)
+ return;
+
+ var req = new MarkChannelAsReadRequest(channel, message);
+
+ req.Success += () => channel.LastReadId = message.Id;
+ req.Failure += e => Logger.Error(e, $"Failed to mark channel {channel} up to '{message}' as read");
+
+ api.Queue(req);
+ }
+
[BackgroundDependencyLoader]
private void load(IAPIProvider api)
{
diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs
index e80c51d82a..45d311df28 100644
--- a/osu.Game/Overlays/ChatOverlay.cs
+++ b/osu.Game/Overlays/ChatOverlay.cs
@@ -279,6 +279,10 @@ namespace osu.Game.Overlays
currentChannelContainer.Clear(false);
currentChannelContainer.Add(loaded);
}
+
+ // mark channel as read when channel switched
+ if (e.NewValue.Messages.Any())
+ channelManager.MarkChannelAsRead(e.NewValue);
}
private float startDragChatHeight;
diff --git a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs
index 27796c1e32..e485aa5ea9 100644
--- a/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/General/LoginSettings.cs
@@ -323,8 +323,6 @@ namespace osu.Game.Overlays.Settings.Sections.General
Colour = Color4.Black.Opacity(0.25f),
Radius = 4,
};
-
- ItemsContainer.Padding = new MarginPadding();
}
[BackgroundDependencyLoader]
diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs
index 35f28ab1b2..55e1937d83 100644
--- a/osu.Game/Overlays/Settings/SettingsItem.cs
+++ b/osu.Game/Overlays/Settings/SettingsItem.cs
@@ -163,10 +163,6 @@ namespace osu.Game.Overlays.Settings
public string TooltipText => "Revert to default";
- protected override bool OnMouseDown(MouseDownEvent e) => true;
-
- protected override bool OnMouseUp(MouseUpEvent e) => true;
-
protected override bool OnClick(ClickEvent e)
{
if (bindable != null && !bindable.Disabled)
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 04d0b580da..4fc9e47119 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 50aabd636a..760600e6d4 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -74,7 +74,7 @@
-
+
@@ -82,7 +82,7 @@
-
+