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 = {
/* 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 */; };
4CE6DEE927F7A08100C66700 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CE6DEE827F7A08100C66700 /* ContentView.swift */; };
4CE6DEEB27F7A08200C66700 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4CE6DEEA27F7A08200C66700 /* Assets.xcassets */; };
@ -37,6 +38,7 @@
/* End PBXContainerItemProxy 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; };
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>"; };
@ -77,6 +79,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
4C75EFA227FA576C0006080F /* Views */ = {
isa = PBXGroup;
children = (
4C75EFA327FA577B0006080F /* PostView.swift */,
);
path = Views;
sourceTree = "<group>";
};
4CE6DEDA27F7A08100C66700 = {
isa = PBXGroup;
children = (
@ -100,6 +110,7 @@
4CE6DEE527F7A08100C66700 /* damus */ = {
isa = PBXGroup;
children = (
4C75EFA227FA576C0006080F /* Views */,
4CE6DEE627F7A08100C66700 /* damusApp.swift */,
4CE6DEE827F7A08100C66700 /* ContentView.swift */,
4CE6DEEA27F7A08200C66700 /* Assets.xcassets */,
@ -275,6 +286,7 @@
4CE6DF1427F7A45200C66700 /* WSConnection.swift in Sources */,
4CE6DF1627F8DEBF00C66700 /* NostrConnection.swift in Sources */,
4CE6DEE727F7A08100C66700 /* damusApp.swift in Sources */,
4C75EFA427FA577B0006080F /* PostView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -361,7 +373,8 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = 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_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
@ -415,7 +428,8 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = 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_FAST_MATH = YES;
SDKROOT = iphoneos;

View File

@ -8,36 +8,111 @@
import SwiftUI
import Starscream
struct ContentView: View {
@State var status: String = "Not connected"
@State var events: [NostrEvent] = []
@State var connection: NostrConnection? = nil
struct EventView: View {
let event: NostrEvent
var body: some View {
ForEach(events, id: \.id) {
Text($0.content)
.padding()
}
.onAppear() {
let url = URL(string: "wss://nostr.bitcoiner.social")!
let conn = NostrConnection(url: url, handleEvent: handle_event)
conn.connect()
self.connection = conn
VStack {
Text(String(event.pubkey.prefix(16)))
.bold()
.onTapGesture {
UIPasteboard.general.string = event.pubkey
}
.frame(maxWidth: .infinity, alignment: .leading)
Text(event.content)
.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) {
switch conn_event {
case .ws_event(let ev):
if case .connected = ev {
self.connection?.send(NostrFilter.filter_since(1648851447))
switch ev {
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)")
case .nostr_event(let ev):
switch 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):
print(msg)
}
@ -50,3 +125,21 @@ struct ContentView_Previews: PreviewProvider {
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)
}
struct NostrSubscription {
let sub_id: String
let filter: NostrFilter
}
struct NostrFilter: Codable {
let ids: [String]?
let kinds: [String]?
@ -114,8 +119,8 @@ class NostrConnection: WebSocketDelegate {
socket.disconnect()
}
func send(_ filter: NostrFilter) {
guard let req = make_nostr_req(filter) else {
func send(_ filter: NostrFilter, sub_id: String) {
guard let req = make_nostr_req(filter, sub_id: sub_id) else {
print("failed to encode nostr req: \(filter)")
return
}
@ -165,14 +170,7 @@ func decode_data<T: Decodable>(_ data: Data) -> T? {
return nil
}
func make_nostr_req(_ filter: NostrFilter) -> String? {
let sub_id = UUID()
var params: [Encodable] = []
params.append("REQ")
params.append(sub_id)
params.append(filter)
func make_nostr_req(_ filter: NostrFilter, sub_id: String) -> String? {
let encoder = JSONEncoder()
guard let filter_json = try? encoder.encode(filter) else {
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)
}
}