mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Delivery Status Redesign (#931)
This commit is contained in:
@@ -30,6 +30,7 @@ final class AppSettings {
|
||||
case startChatFlowEnabled
|
||||
case startChatUserSuggestionsEnabled
|
||||
case invitesFlowEnabled
|
||||
case readReceiptsEnabled
|
||||
}
|
||||
|
||||
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
||||
@@ -186,4 +187,9 @@ final class AppSettings {
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.invitesFlowEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var invitesFlowEnabled
|
||||
|
||||
// MARK: Receipts
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.readReceiptsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||
var readReceiptsEnabled
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@ struct RoomScreen: View {
|
||||
RoomAttachmentPicker(context: context)
|
||||
messageComposer
|
||||
}
|
||||
.padding()
|
||||
.padding([.horizontal, .bottom])
|
||||
.padding(.top, 8)
|
||||
}
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
struct TimelineItemBubbledStylerView<Content: View, DeliveryStatus: View>: View {
|
||||
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||
@Environment(\.timelineGroupStyle) private var timelineGroupStyle
|
||||
|
||||
let timelineItem: EventBasedTimelineItemProtocol
|
||||
@ViewBuilder let content: () -> Content
|
||||
@ViewBuilder let deliveryStatus: () -> DeliveryStatus
|
||||
|
||||
@ScaledMetric private var senderNameVerticalPadding = 3
|
||||
private let cornerRadius: CGFloat = 12
|
||||
@@ -45,10 +46,6 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
.padding(.horizontal, 16.0)
|
||||
.padding(timelineItem.isOutgoing ? .leading : .trailing, 40) // Extra padding to differentiate alignment.
|
||||
}
|
||||
|
||||
if let deliveryStatus = timelineItem.properties.deliveryStatus {
|
||||
TimelineDeliveryStatusView(deliveryStatus: deliveryStatus)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +82,10 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
context.send(viewAction: .sendReaction(key: key, eventID: timelineItem.id))
|
||||
}
|
||||
}
|
||||
|
||||
deliveryStatus()
|
||||
.padding(.top, 10)
|
||||
.padding(.bottom, 3)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +116,13 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
.font(.compound.bodyXS)
|
||||
.foregroundColor(.element.tertiaryContent)
|
||||
}
|
||||
|
||||
if timelineItem.properties.deliveryStatus == .sendingFailed {
|
||||
Image(systemName: "exclamationmark.circle.fill")
|
||||
.resizable()
|
||||
.foregroundColor(.element.alert)
|
||||
.frame(width: 16, height: 16)
|
||||
}
|
||||
}
|
||||
.bubbleStyle(inset: true,
|
||||
color: timelineItem.isOutgoing ? .element.bubblesYou : .element.bubblesNotYou,
|
||||
|
||||
@@ -17,29 +17,29 @@
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
struct TimelineItemPlainStylerView<Content: View>: View {
|
||||
struct TimelineItemPlainStylerView<Content: View, DeliveryStatus: View>: View {
|
||||
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||
@Environment(\.timelineGroupStyle) private var timelineGroupStyle
|
||||
|
||||
let timelineItem: EventBasedTimelineItemProtocol
|
||||
@ViewBuilder let content: () -> Content
|
||||
@ViewBuilder let deliveryStatus: () -> DeliveryStatus
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
header
|
||||
|
||||
VStack(alignment: .trailing) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(alignment: .firstTextBaseline) {
|
||||
contentWithReply
|
||||
|
||||
Spacer()
|
||||
|
||||
if let deliveryStatus = timelineItem.properties.deliveryStatus {
|
||||
TimelineDeliveryStatusView(deliveryStatus: deliveryStatus)
|
||||
header
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(alignment: .firstTextBaseline) {
|
||||
contentWithReply
|
||||
|
||||
Spacer()
|
||||
}
|
||||
supplementaryViews
|
||||
}
|
||||
supplementaryViews
|
||||
}
|
||||
deliveryStatus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@ struct TimelineItemPlainStylerView<Content: View>: View {
|
||||
|
||||
content()
|
||||
}
|
||||
.contextMenu {
|
||||
context.viewState.contextMenuActionProvider?(timelineItem.id).map { actions in
|
||||
TimelineItemContextMenu(itemID: timelineItem.id, contextMenuActions: actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
|
||||
@@ -21,6 +21,12 @@ import SwiftUI
|
||||
|
||||
struct TimelineStyler<Content: View>: View {
|
||||
@Environment(\.timelineStyle) private var style
|
||||
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||
|
||||
private var isLastOutgoingMessage: Bool {
|
||||
context.viewState.items.last(where: { !$0.isUnsent })?.id == timelineItem.id &&
|
||||
timelineItem.isOutgoing
|
||||
}
|
||||
|
||||
let timelineItem: EventBasedTimelineItemProtocol
|
||||
@ViewBuilder let content: () -> Content
|
||||
@@ -28,9 +34,96 @@ struct TimelineStyler<Content: View>: View {
|
||||
var body: some View {
|
||||
switch style {
|
||||
case .plain:
|
||||
TimelineItemPlainStylerView(timelineItem: timelineItem, content: content)
|
||||
TimelineItemPlainStylerView(timelineItem: timelineItem, content: content) {
|
||||
deliveryStatusView
|
||||
}
|
||||
case .bubbles:
|
||||
TimelineItemBubbledStylerView(timelineItem: timelineItem, content: content)
|
||||
TimelineItemBubbledStylerView(timelineItem: timelineItem, content: content) {
|
||||
deliveryStatusView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var deliveryStatusView: some View {
|
||||
switch timelineItem.properties.deliveryStatus {
|
||||
case .sending:
|
||||
TimelineDeliveryStatusView(deliveryStatus: .sending)
|
||||
case .sent:
|
||||
TimelineDeliveryStatusView(deliveryStatus: .sent)
|
||||
case .none:
|
||||
if isLastOutgoingMessage {
|
||||
// We always display the sent icon for the latest echoed outgoing message
|
||||
TimelineDeliveryStatusView(deliveryStatus: .sent)
|
||||
}
|
||||
case .sendingFailed:
|
||||
if style == .plain {
|
||||
Image(systemName: "exclamationmark.circle.fill")
|
||||
.resizable()
|
||||
.foregroundColor(.element.alert)
|
||||
.frame(width: 16, height: 16)
|
||||
}
|
||||
// The bubbles handle the failure internally
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TimelineItemStyler_Previews: PreviewProvider {
|
||||
static let viewModel = RoomScreenViewModel.mock
|
||||
|
||||
static let base = TextRoomTimelineItem(id: UUID().uuidString, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: ""))
|
||||
|
||||
static let sent: TextRoomTimelineItem = {
|
||||
var result = base
|
||||
result.properties.deliveryStatus = .sent
|
||||
return result
|
||||
}()
|
||||
|
||||
static let sending: TextRoomTimelineItem = {
|
||||
var result = base
|
||||
result.properties.deliveryStatus = .sending
|
||||
return result
|
||||
}()
|
||||
|
||||
static let failed: TextRoomTimelineItem = {
|
||||
var result = base
|
||||
result.properties.deliveryStatus = .sendingFailed
|
||||
return result
|
||||
}()
|
||||
|
||||
static let last: TextRoomTimelineItem = {
|
||||
let id = viewModel.state.items.last?.id ?? UUID().uuidString
|
||||
let result = TextRoomTimelineItem(id: id, timestamp: "Now", isOutgoing: true, isEditable: false, sender: .init(id: UUID().uuidString), content: .init(body: ""))
|
||||
return result
|
||||
}()
|
||||
|
||||
static var testView: some View {
|
||||
VStack {
|
||||
TimelineStyler(timelineItem: sent) {
|
||||
Text("Sent")
|
||||
}
|
||||
TimelineStyler(timelineItem: sending) {
|
||||
Text("Sending")
|
||||
}
|
||||
TimelineStyler(timelineItem: base) {
|
||||
Text("Normal")
|
||||
}
|
||||
TimelineStyler(timelineItem: last) {
|
||||
Text("Last")
|
||||
}
|
||||
TimelineStyler(timelineItem: failed) {
|
||||
Text("Failed")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
testView
|
||||
.environmentObject(viewModel.context)
|
||||
.environment(\.timelineStyle, .bubbles)
|
||||
|
||||
testView
|
||||
.environmentObject(viewModel.context)
|
||||
.environment(\.timelineStyle, .plain)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-28
@@ -16,45 +16,27 @@
|
||||
|
||||
import SwiftUI
|
||||
struct TimelineDeliveryStatusView: View {
|
||||
let deliveryStatus: TimelineItemDeliveryStatus
|
||||
|
||||
@State var showDeliveryStatus: Bool
|
||||
|
||||
enum Status {
|
||||
case sending
|
||||
case sent
|
||||
}
|
||||
|
||||
let deliveryStatus: Status
|
||||
|
||||
private var systemImageName: String {
|
||||
switch deliveryStatus {
|
||||
case .sending:
|
||||
return "circle"
|
||||
case .sent:
|
||||
return "checkmark.circle"
|
||||
case .sendingFailed:
|
||||
return "exclamationmark.circle"
|
||||
}
|
||||
}
|
||||
|
||||
init(deliveryStatus: TimelineItemDeliveryStatus) {
|
||||
self.deliveryStatus = deliveryStatus
|
||||
|
||||
switch deliveryStatus {
|
||||
case .sending, .sendingFailed:
|
||||
showDeliveryStatus = true
|
||||
case let .sent(elapsedTime: elapsedTime):
|
||||
showDeliveryStatus = elapsedTime < 3
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
Image(systemName: systemImageName)
|
||||
.resizable()
|
||||
.frame(width: 12.0, height: 12.0)
|
||||
.opacity(showDeliveryStatus ? 1.0 : 0.0)
|
||||
.task {
|
||||
if case .sent = deliveryStatus {
|
||||
try? await Task.sleep(nanoseconds: 1_000_000_000)
|
||||
withAnimation {
|
||||
showDeliveryStatus = false
|
||||
}
|
||||
}
|
||||
}
|
||||
.foregroundColor(.element.secondaryContent)
|
||||
.frame(width: 16.0, height: 16.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +44,7 @@ struct TimelineDeliveryStatusView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
VStack {
|
||||
TimelineDeliveryStatusView(deliveryStatus: .sending)
|
||||
TimelineDeliveryStatusView(deliveryStatus: .sent(elapsedTime: Date().timeIntervalSince1970))
|
||||
TimelineDeliveryStatusView(deliveryStatus: .sent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,6 +22,6 @@ struct RoomTimelineItemProperties: Hashable {
|
||||
var isEdited = false
|
||||
/// The aggregated reactions that have been sent for this item.
|
||||
var reactions: [AggregatedReaction] = []
|
||||
/// The delivery status for this item.
|
||||
/// The delivery status for this item. If a sent message is echoed the value is nil.
|
||||
var deliveryStatus: TimelineItemDeliveryStatus?
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ enum TimelineItemProxy {
|
||||
/// The delivery status for the item.
|
||||
enum TimelineItemDeliveryStatus: Hashable {
|
||||
case sending
|
||||
case sent(elapsedTime: TimeInterval)
|
||||
case sent
|
||||
case sendingFailed
|
||||
}
|
||||
|
||||
@@ -54,7 +54,9 @@ struct EventTimelineItemProxy {
|
||||
}
|
||||
|
||||
var deliveryStatus: TimelineItemDeliveryStatus? {
|
||||
guard let localSendState = item.localSendState() else { return nil }
|
||||
guard let localSendState = item.localSendState() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch localSendState {
|
||||
case .notSentYet:
|
||||
@@ -62,7 +64,7 @@ struct EventTimelineItemProxy {
|
||||
case .sendingFailed:
|
||||
return .sendingFailed
|
||||
case .sent:
|
||||
return .sent(elapsedTime: Date().timeIntervalSince1970 - timestamp.timeIntervalSince1970)
|
||||
return .sent
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +111,10 @@ struct EventTimelineItemProxy {
|
||||
let debugInfo = item.debugInfo()
|
||||
return TimelineItemDebugInfo(model: debugInfo.model, originalJSON: debugInfo.originalJson, latestEditJSON: debugInfo.latestEditJson)
|
||||
}
|
||||
|
||||
var readReceipts: [String: Receipt] {
|
||||
item.readReceipts()
|
||||
}
|
||||
}
|
||||
|
||||
extension TimelineItemContentKind {
|
||||
@@ -162,3 +168,12 @@ struct TimelineItemDebugInfo: Identifiable, CustomStringConvertible {
|
||||
return String(data: jsonData, encoding: .utf8)
|
||||
}
|
||||
}
|
||||
|
||||
extension Receipt {
|
||||
var dateTimestamp: Date? {
|
||||
guard let timestamp else {
|
||||
return nil
|
||||
}
|
||||
return Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
|
||||
fatalError("Unknown timeline item")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var id: String {
|
||||
switch self {
|
||||
case .text(let item as RoomTimelineItemProtocol, _),
|
||||
@@ -100,6 +100,26 @@ enum RoomTimelineViewProvider: Identifiable, Hashable {
|
||||
return item.id
|
||||
}
|
||||
}
|
||||
|
||||
var isUnsent: Bool {
|
||||
switch self {
|
||||
case .text(let item as EventBasedTimelineItemProtocol, _),
|
||||
.image(let item as EventBasedTimelineItemProtocol, _),
|
||||
.video(let item as EventBasedTimelineItemProtocol, _),
|
||||
.audio(let item as EventBasedTimelineItemProtocol, _),
|
||||
.file(let item as EventBasedTimelineItemProtocol, _),
|
||||
.emote(let item as EventBasedTimelineItemProtocol, _),
|
||||
.notice(let item as EventBasedTimelineItemProtocol, _),
|
||||
.redacted(let item as EventBasedTimelineItemProtocol, _),
|
||||
.encrypted(let item as EventBasedTimelineItemProtocol, _),
|
||||
.sticker(let item as EventBasedTimelineItemProtocol, _),
|
||||
.unsupported(let item as EventBasedTimelineItemProtocol, _),
|
||||
.state(let item as EventBasedTimelineItemProtocol, _):
|
||||
return item.properties.deliveryStatus == .sending || item.properties.deliveryStatus == .sendingFailed
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether or not it is possible to send a reaction to this timeline item.
|
||||
var isReactable: Bool {
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6fb7862fb96c989a30077ea6a91c1b550b6bff2dec6095ecba54813a4e87a91e
|
||||
size 226885
|
||||
oid sha256:0e61e6dccf47027af9b1d9d40b28a38ab9b75b4455cfc4dd93835748caf095b7
|
||||
size 226144
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2781f8b12a7c359ed0aba73b2601d713a152a4c6fdd1a76115d6c214c1bf4a8c
|
||||
size 265581
|
||||
oid sha256:72f234c5fe48fb4a1faa736c34d35a9bb693c3d3fa2b729a09df0602ca072ef5
|
||||
size 266282
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c0a6edbb32843b33c62cb0ab10a0c461c0704bb75c61e20f37a7a57c517a3a52
|
||||
size 226770
|
||||
oid sha256:23c7126fd1fa69e482220b3a1e1fc3608b72e8a7dacb1f2abf5b8d5b95befb1b
|
||||
size 226023
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f62df61b8daf07b747463042153b0726d0aff05b439978524316ebac52229ecc
|
||||
size 95571
|
||||
oid sha256:1071fdafcad66664288bc18505f733829f045c07faecaeb36d62be896262a3a8
|
||||
size 96975
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a03a58ed11fef52767c27fbf6475f8ca91de31ecc0543e8861a27f30b7b62793
|
||||
size 116521
|
||||
oid sha256:8f8de7ead20eef42d189b3582169783eaa037478ca43c9f1004f216abfc2b3e9
|
||||
size 116418
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a630be82b6722a76407e608018e75b1798a218bcf7aaf25e5908c6f96862e274
|
||||
size 284402
|
||||
oid sha256:a3204698079695ad6197fbdba23e1e45322f3981a202019bbedf44fda401dc4d
|
||||
size 284896
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a66665604f91d490c85acaba6941de9dbc4ca772bd079eabbd78efc821841886
|
||||
size 349022
|
||||
oid sha256:891bd87182b1ce91da99b4748b4c951eeea0f8cb81355628a3f6cf75d97c1e6a
|
||||
size 350090
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4f20d74ceaa84e10c81ec2be3a2a8cd272f7beeeb9dc1c2938ff24b838d4c4dd
|
||||
size 241625
|
||||
oid sha256:71b1a302c3013f61056be9c3aad8d429aad25f402a38b7ad47fca32999b6e5d3
|
||||
size 248611
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:cda777f0e512812d9f7fcd35558c8d80e04f920076378a6877e026aabfec8a18
|
||||
size 348778
|
||||
oid sha256:2d5cf517ea15a9a5fdfcacc858b7b3173cdc1a9bda0afa975b4e271f4afdc0c9
|
||||
size 349837
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5a56ebd80da6117480d23ca1ed8014ce47c45535955918680952ebf73f9116a4
|
||||
size 147486
|
||||
oid sha256:7109c790683af45b2f29fd0a6aa8496ac09325e48a15a27d6abde5212139acad
|
||||
size 150619
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f2a7499922b564356c7b979a70822ef661a2e0ab683a287ea36d45b10b8b9def
|
||||
size 181749
|
||||
oid sha256:b7c6bac06cdaa0b3f126eecbfe1cf232ac34707e065f13fbaf68708c58cf2293
|
||||
size 181693
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c89e1ad93fc384c9f411dc7c30c5b3f62f07728e73d833755fa52d5079dcfa98
|
||||
size 301035
|
||||
oid sha256:1961e6e76df75e7d3fcb5e385fa66f5d8895e0dc3a48d5b12d42ef37253488ec
|
||||
size 302074
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2733eeae5ecc6a5bf22e7a7e5426ddec69a78ed0952c4b7220e5910ccaae7ae9
|
||||
size 228223
|
||||
oid sha256:6ee1d5f6d28f2edc5fa5446e8e9df6268df8e543dd83230f05001f6a502b54da
|
||||
size 227470
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:61c050c837145b2b526e914fd60f2a8f4a99f2eef59b88135e8753e76973b17c
|
||||
size 265983
|
||||
oid sha256:c80d586a3bac65665769abdaea9bd94819eb0e5796aa5b84d668638124e95b73
|
||||
size 266691
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:385cc5ee090f85667a70689fc46a212d0dce020d2b381b8fc29c1d678a27ba22
|
||||
size 228111
|
||||
oid sha256:6e24bd90d4861049fd1473e81e237f35253063544fa5205ead132566fa3f4c76
|
||||
size 227347
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6123d80a2e17087302f0703483235e55ca10a1b1d145ef24af17e1d70ddc16f2
|
||||
size 96064
|
||||
oid sha256:7590bf3ce258bd1ed83674c7aa8fe029cc6b65cc789e60db6c5aac75f88de1c5
|
||||
size 97468
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b99b3cc08cfc075ce0e1227c120664fe0180e44c37254907630316b64837f5de
|
||||
size 116997
|
||||
oid sha256:aff34dd5e386da4c9491eb19bcb6e2ecd40301640be3768f04f40b2f447dcda2
|
||||
size 116895
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d4d7392606a1eeb82c847ad170e6b0d7e0059eb65b1b7d02bb61a8a9188d17ad
|
||||
size 284875
|
||||
oid sha256:55e1b3c880fc7589c9d955605e16d3df33d842d37fff91efd31acc787d817ee6
|
||||
size 285371
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:15b2a6aaa9b256eaaa580843fd089825067ff1501a78376a4504d7bfcc690493
|
||||
size 349600
|
||||
oid sha256:270122db18781f10a4357610bec368381c8977f36cd81ebabd16ab8abefae822
|
||||
size 350678
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f3b361a6c045cf067e788ff7726e5ad821c4d57796a40fcbc17296002955fab6
|
||||
size 242272
|
||||
oid sha256:8fb535d6c0766d034d32cf2488acbee08053d620dec8f33570506073eca44af7
|
||||
size 249202
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5a936985a9dfc97a33afc709404cad0661a9801f23dd64f56a334c81da981c23
|
||||
size 349356
|
||||
oid sha256:d11402df691d0fce38b74683a8e3e21915ad592ce8ef9a72c6a0947e8a5af30d
|
||||
size 350425
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:49070bf6438d39cf70eed78f4fcfee31824ec97f2b80dffea5b4557827336667
|
||||
size 148046
|
||||
oid sha256:8feb34445e1fcb0d2fe2061a225428f5658436a8821a722b31fefb6e0063f7c8
|
||||
size 151125
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:724f9e598a2e0ae454536de50cca057eb6f3d880b845fdac876c7a34d500c5a5
|
||||
size 182302
|
||||
oid sha256:26051b89f610c6d5810559df462951cbe4f82ba0dba02568d27052ec7ce895f1
|
||||
size 182242
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d4e2d7ccab6079a25d9a7692f2aad2e6bc82f4643f4a8703b92cc561f5723528
|
||||
size 301620
|
||||
oid sha256:7484ae40068b388b98e271f962529e44c67b514c2e8a7bac934bfbbfeb4b9903
|
||||
size 302656
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Added the context menu to the plain style.
|
||||
@@ -0,0 +1 @@
|
||||
Redesigned the delivery status icon.
|
||||
Reference in New Issue
Block a user