oficina / sheets Public

Clone
git clone https://amadan.net/oficina/sheets

Plain git — no account needed to clone.

Download

Download this file

1import Foundation
2import RastrilloApple
3
4@MainActor extension SheetModel {
5 @discardableResult func write(_ writes: [CellWrite], retrying: Bool = false) async -> Bool {
6 guard failedWrites.isEmpty || retrying else {
7 error = "Retry or discard the pending edits before making another change."
8 return false
9 }
10 guard mayWrite && !busy else { return false }
11 guard writes.allSatisfy({ $0.raw.utf8.count <= 8192 }) else {
12 error = "A cell exceeds the input size limit. Nothing was changed."
13 return false
14 }
15 if writes.isEmpty { return true }
16 busy = true
17 defer { busy = false }
18 var offset = 0
19 do {
20 while offset < writes.count {
21 let batch = try await wire.encode(writes, startingAt: offset)
22 let count = batch.count
23 let data = batch.data
24 let (bytes, status) = try await client.response(
25 grid + "/cells/batch", method: "POST", body: data, maxBytes: 64 << 20)
26 guard (200..<300).contains(status) else {
27 throw NativeClientError.message("The server did not confirm the edit.")
28 }
29 let response = try await wire.decode(bytes)
30 await accept(response)
31 offset += count
32 }
33 failedWrites = []
34 error = ""
35 notice = "Saved"
36 if showTable { await loadTable() }
37 return true
38 } catch {
39 failedWrites = Array(writes.dropFirst(offset))
40 self.error =
41 "\(offset) cells confirmed; \(failedWrites.count) still need saving. "
42 + error.localizedDescription
43 return false
44 }
45 }
46 func retryWrites() async {
47 let pending = failedWrites
48 if await write(pending, retrying: true), pending.count == 1, let value = pending.first,
49 value.r == selection.start.r, value.c == selection.start.c, value.raw == draft
50 {
51 originalDraft = draft
52 }
53 }
54}
55