1
0
mirror of git://jb55.com/damus synced 2024-10-01 09:20:47 +00:00

better main view, add initial post view

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin 2022-04-03 15:40:18 -07:00
parent f4bb07081f
commit dc376a4a72
5 changed files with 156 additions and 81 deletions

View File

@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
4C75EFA427FA577B0006080F /* PostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C75EFA327FA577B0006080F /* PostView.swift */; };
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE627F7A08100C66700 /* damusApp.swift */; }; 4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE627F7A08100C66700 /* damusApp.swift */; };
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; }; 4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
4CE6DEEB27F7A08200C66700 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4CE6DEEA27F7A08200C66700 /* Assets.xcassets */; }; 4CE6DEEB27F7A08200C66700 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4CE6DEEA27F7A08200C66700 /* Assets.xcassets */; };
@ -37,6 +38,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
4C75EFA327FA577B0006080F /* PostView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostView.swift; sourceTree = "<group>"; };
4CE6DEE327F7A08100C66700 /* damus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = damus.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4CE6DEE327F7A08100C66700 /* damus.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = damus.app; sourceTree = BUILT_PRODUCTS_DIR; };
4CE6DEE627F7A08100C66700 /* damusApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = damusApp.swift; sourceTree = "<group>"; }; 4CE6DEE627F7A08100C66700 /* damusApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = damusApp.swift; sourceTree = "<group>"; };
4CE6DEE827F7A08100C66700 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; 4CE6DEE827F7A08100C66700 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
@ -77,6 +79,14 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
4C75EFA227FA576C0006080F /* Views */ = {
isa = PBXGroup;
children = (
4C75EFA327FA577B0006080F /* PostView.swift */,
);
path = Views;
sourceTree = "<group>";
};
4CE6DEDA27F7A08100C66700 = { 4CE6DEDA27F7A08100C66700 = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -100,6 +110,7 @@
4CE6DEE527F7A08100C66700 /* damus */ = { 4CE6DEE527F7A08100C66700 /* damus */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4C75EFA227FA576C0006080F /* Views */,
4CE6DEE627F7A08100C66700 /* damusApp.swift */, 4CE6DEE627F7A08100C66700 /* damusApp.swift */,
4CE6DEE827F7A08100C66700 /* ContentView.swift */, 4CE6DEE827F7A08100C66700 /* ContentView.swift */,
4CE6DEEA27F7A08200C66700 /* Assets.xcassets */, 4CE6DEEA27F7A08200C66700 /* Assets.xcassets */,
@ -275,6 +286,7 @@
4CE6DF1427F7A45200C66700 /* WSConnection.swift in Sources */, 4CE6DF1427F7A45200C66700 /* WSConnection.swift in Sources */,
4CE6DF1627F8DEBF00C66700 /* NostrConnection.swift in Sources */, 4CE6DF1627F8DEBF00C66700 /* NostrConnection.swift in Sources */,
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */, 4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */,
4C75EFA427FA577B0006080F /* PostView.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -361,7 +373,8 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.4; IPHONEOS_DEPLOYMENT_TARGET = 15.3;
MACOSX_DEPLOYMENT_TARGET = 12.3;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
@ -415,7 +428,8 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 15.4; IPHONEOS_DEPLOYMENT_TARGET = 15.3;
MACOSX_DEPLOYMENT_TARGET = 12.3;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;

View File

@ -8,36 +8,111 @@
import SwiftUI import SwiftUI
import Starscream import Starscream
struct ContentView: View { struct EventView: View {
@State var status: String = "Not connected" let event: NostrEvent
@State var events: [NostrEvent] = []
@State var connection: NostrConnection? = nil
var body: some View { var body: some View {
ForEach(events, id: \.id) { VStack {
Text($0.content) Text(String(event.pubkey.prefix(16)))
.padding() .bold()
} .onTapGesture {
.onAppear() { UIPasteboard.general.string = event.pubkey
let url = URL(string: "wss://nostr.bitcoiner.social")! }
let conn = NostrConnection(url: url, handleEvent: handle_event) .frame(maxWidth: .infinity, alignment: .leading)
conn.connect() Text(event.content)
self.connection = conn .textSelection(.enabled)
.frame(maxWidth: .infinity, alignment: .leading)
Divider()
} }
} }
}
enum Sheets: Identifiable {
case post
var id: String {
switch self {
case .post:
return "post"
}
}
}
struct ContentView: View {
@State var status: String = "Not connected"
@State var sub_id: String? = nil
@State var active_sheet: Sheets? = nil
@State var events: [NostrEvent] = []
@State var connection: NostrConnection? = nil
var MainContent: some View {
ScrollView {
ForEach(events.reversed(), id: \.id) {
EventView(event: $0)
}
}
}
var body: some View {
ZStack {
MainContent
VStack {
Spacer()
HStack {
Spacer()
PostButton {
self.active_sheet = .post
}
}
}
}
.onAppear() {
self.connect()
}
.sheet(item: $active_sheet) { item in
switch item {
case .post:
PostView()
}
}
}
func connect() {
let url = URL(string: "wss://nostr.bitcoiner.social")!
let conn = NostrConnection(url: url, handleEvent: handle_event)
conn.connect()
self.connection = conn
}
func handle_event(conn_event: NostrConnectionEvent) { func handle_event(conn_event: NostrConnectionEvent) {
switch conn_event { switch conn_event {
case .ws_event(let ev): case .ws_event(let ev):
if case .connected = ev { switch ev {
self.connection?.send(NostrFilter.filter_since(1648851447)) case .connected:
let now = Int64(Date().timeIntervalSince1970)
let yesterday = now - 24 * 60 * 60
let filter = NostrFilter.filter_since(yesterday)
let sub_id = self.sub_id ?? UUID().description
if self.sub_id != sub_id {
self.sub_id = sub_id
}
self.connection?.send(filter, sub_id: sub_id)
case .cancelled:
self.connection?.connect()
default:
break
} }
print("ws_event \(ev)") print("ws_event \(ev)")
case .nostr_event(let ev): case .nostr_event(let ev):
switch ev { switch ev {
case .event(_, let ev): case .event(_, let ev):
self.events.append(ev) self.sub_id = sub_id
if ev.kind == 1 {
self.events.append(ev)
}
print(ev)
case .notice(let msg): case .notice(let msg):
print(msg) print(msg)
} }
@ -50,3 +125,21 @@ struct ContentView_Previews: PreviewProvider {
ContentView() ContentView()
} }
} }
func PostButton(action: @escaping () -> ()) -> some View {
return Button(action: action, label: {
Text("+")
.font(.system(.largeTitle))
.frame(width: 67, height: 60)
.foregroundColor(Color.white)
.padding(.bottom, 7)
})
.background(Color.blue)
.cornerRadius(38.5)
.padding()
.shadow(color: Color.black.opacity(0.3),
radius: 3,
x: 3,
y: 3)
}

View File

@ -28,6 +28,11 @@ enum NostrTag {
case key_event(KeyEvent) case key_event(KeyEvent)
} }
struct NostrSubscription {
let sub_id: String
let filter: NostrFilter
}
struct NostrFilter: Codable { struct NostrFilter: Codable {
let ids: [String]? let ids: [String]?
let kinds: [String]? let kinds: [String]?
@ -114,8 +119,8 @@ class NostrConnection: WebSocketDelegate {
socket.disconnect() socket.disconnect()
} }
func send(_ filter: NostrFilter) { func send(_ filter: NostrFilter, sub_id: String) {
guard let req = make_nostr_req(filter) else { guard let req = make_nostr_req(filter, sub_id: sub_id) else {
print("failed to encode nostr req: \(filter)") print("failed to encode nostr req: \(filter)")
return return
} }
@ -165,14 +170,7 @@ func decode_data<T: Decodable>(_ data: Data) -> T? {
return nil return nil
} }
func make_nostr_req(_ filter: NostrFilter) -> String? { func make_nostr_req(_ filter: NostrFilter, sub_id: String) -> String? {
let sub_id = UUID()
var params: [Encodable] = []
params.append("REQ")
params.append(sub_id)
params.append(filter)
let encoder = JSONEncoder() let encoder = JSONEncoder()
guard let filter_json = try? encoder.encode(filter) else { guard let filter_json = try? encoder.encode(filter) else {
return nil return nil

View File

@ -0,0 +1,20 @@
//
// Post.swift
// damus
//
// Created by William Casarin on 2022-04-03.
//
import SwiftUI
struct PostView: View {
var body: some View {
Text("New post")
}
}
struct Post_Previews: PreviewProvider {
static var previews: some View {
PostView()
}
}

View File

@ -1,50 +0,0 @@
//
// Connection.swift
// damus
//
// Created by William Casarin on 2022-04-01.
//
import Foundation
import Starscream
class WSConnection: WebSocketDelegate {
var isConnected: Bool = false
var socket: WebSocket
var handleEvent: (WebSocketEvent) -> ()
init(url: URL, handleEvent: @escaping (WebSocketEvent) -> ()) {
var req = URLRequest(url: url)
req.timeoutInterval = 5
self.socket = WebSocket(request: req)
self.handleEvent = handleEvent
socket.delegate = self
}
func connect(){
socket.connect()
}
func disconnect() {
socket.disconnect()
}
func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .connected:
self.isConnected = true
case .disconnected: fallthrough
case .cancelled: fallthrough
case .error:
self.isConnected = false
default:
break
}
handleEvent(event)
}
}