aboutsummaryrefslogtreecommitdiff
path: root/iGopherBrowser/BrowserView.swift
diff options
context:
space:
mode:
authorNavan Chauhan <navanchauhan@gmail.com>2023-12-19 16:11:26 -0700
committerNavan Chauhan <navanchauhan@gmail.com>2023-12-19 16:11:26 -0700
commit98d58bf5284f6fce850cb7f80aec16b9b5f701eb (patch)
tree1a1088c1019d29081aebcb2957fc60163215959f /iGopherBrowser/BrowserView.swift
parenta68c43b716b92a932ec1d405cc9e182cdab7d5a3 (diff)
fix and format
Diffstat (limited to 'iGopherBrowser/BrowserView.swift')
-rw-r--r--iGopherBrowser/BrowserView.swift595
1 files changed, 307 insertions, 288 deletions
diff --git a/iGopherBrowser/BrowserView.swift b/iGopherBrowser/BrowserView.swift
index 663851c..9aa45cc 100644
--- a/iGopherBrowser/BrowserView.swift
+++ b/iGopherBrowser/BrowserView.swift
@@ -5,312 +5,331 @@
// Created by Navan Chauhan on 12/16/23.
//
+import GopherHelpers
import SwiftUI
import swiftGopherClient
-import GopherHelpers
struct BrowserView: View {
-
- @State var url: String = ""
- @State private var gopherItems: [gopherItem] = []
-
- @Binding public var hosts: [GopherNode]
- @Binding var selectedNode: GopherNode?
-
- @State private var backwardStack: [GopherNode] = []
- @State private var forwardStack: [GopherNode] = []
-
- @State private var searchText: String = ""
- @State private var showSearchInput = false
- @State var selectedSearchItem: Int?
-
- let client = GopherClient()
-
- var body: some View {
- NavigationStack {
- VStack(spacing: 0) {
- if (gopherItems.count >= 1) {
- List {
- ForEach(Array(gopherItems.enumerated()), id: \.offset) { idx, item in
- if item.parsedItemType == .info {
- Text(item.message)
- .font(.system(size: 12, design: .monospaced))
- .frame(height: 20)
- .listRowInsets(EdgeInsets())
- .listRowSeparator(.hidden)
- } else if item.parsedItemType == .directory {
- HStack {
- Text(Image(systemName: "folder"))
- Text(item.message)
- Spacer()
- }.onTapGesture {
- performGopherRequest(host: item.host, port: item.port, selector: item.selector)
- }
- } else if item.parsedItemType == .search {
- HStack {
- Text(Image(systemName: "magnifyingglass"))
- Text(item.message)
- Spacer()
- }.onTapGesture {
- self.selectedSearchItem = idx
- self.showSearchInput = true
- }
- } else if item.parsedItemType == .text {
- NavigationLink(destination: FileView(item: item)) {
- HStack {
- Text(Image(systemName: "doc.plaintext"))
- Text(item.message)
- Spacer()
- }
- }
- } else if [.doc, .image, .gif, .movie, .sound, .bitmap].contains(item.parsedItemType) {
- NavigationLink(destination: FileView(item: item)) {
- HStack {
- Text(Image(systemName: itemToImageType(item)))
- Text(item.message)
- Spacer()
- }
- }
- } else {
- Text(item.message)
- .onTapGesture {
- performGopherRequest(host: item.host, port: item.port, selector: item.selector)
- }
-
- }
- }
- }
- .background(Color.white)
- .cornerRadius(10)
- .sheet(isPresented: $showSearchInput) {
- if let index = selectedSearchItem, gopherItems.indices.contains(index) {
- let searchItem = gopherItems[index]
- SearchInputView(
- host: searchItem.host,
- port: searchItem.port,
- selector: searchItem.selector,
- searchText: $searchText,
- onSearch: { query in
- performGopherRequest(host: searchItem.host, port: searchItem.port, selector: "\(searchItem.selector)\t\(query)")
- showSearchInput = false
- }
- )
- } else {
-
- VStack {
- Text("Weird bug. Please Dismiss -> Press Go -> Try Again")
- Button("Dismiss") {
- self.showSearchInput = false
- }
- }
-
- }
- }
- } else {
+
+ @State var url: String = ""
+ @State private var gopherItems: [gopherItem] = []
+
+ @Binding public var hosts: [GopherNode]
+ @Binding var selectedNode: GopherNode?
+
+ @State private var backwardStack: [GopherNode] = []
+ @State private var forwardStack: [GopherNode] = []
+
+ @State private var searchText: String = ""
+ @State private var showSearchInput = false
+ @State var selectedSearchItem: Int?
+
+ let client = GopherClient()
+
+ var body: some View {
+ NavigationStack {
+ VStack(spacing: 0) {
+ if gopherItems.count >= 1 {
+ List {
+ ForEach(Array(gopherItems.enumerated()), id: \.offset) { idx, item in
+ if item.parsedItemType == .info {
+ Text(item.message)
+ .font(.system(size: 12, design: .monospaced))
+ .frame(height: 20)
+ .listRowInsets(EdgeInsets())
+ .listRowSeparator(.hidden)
+ } else if item.parsedItemType == .directory {
+ HStack {
+ Text(Image(systemName: "folder"))
+ Text(item.message)
+ Spacer()
+ }.onTapGesture {
+ performGopherRequest(host: item.host, port: item.port, selector: item.selector)
+ }
+ } else if item.parsedItemType == .search {
+ HStack {
+ Text(Image(systemName: "magnifyingglass"))
+ Text(item.message)
+ Spacer()
+ }.onTapGesture {
+ self.selectedSearchItem = idx
+ self.showSearchInput = true
+ }
+ } else if item.parsedItemType == .text {
+ NavigationLink(destination: FileView(item: item)) {
+ HStack {
+ Text(Image(systemName: "doc.plaintext"))
+ Text(item.message)
Spacer()
- Text("Welcome to iGopher Browser")
+ }
+ }
+ } else if [.doc, .image, .gif, .movie, .sound, .bitmap].contains(item.parsedItemType)
+ {
+ NavigationLink(destination: FileView(item: item)) {
+ HStack {
+ Text(Image(systemName: itemToImageType(item)))
+ Text(item.message)
Spacer()
+ }
}
- #if os(iOS)
- VStack {
- HStack(spacing: 10) {
- HStack {
- Spacer()
+ } else {
+ Text(item.message)
+ .onTapGesture {
+ performGopherRequest(host: item.host, port: item.port, selector: item.selector)
+ }
-
-
- TextField("Enter a URL", text: $url)
- #if !os(OSX)
- .keyboardType(.URL)
- .autocapitalization(.none)
- #endif
- .padding(10)
- Spacer()
- }
- //.background(Color.white)
- .cornerRadius(30)
-
- Button("Go", action: {
- performGopherRequest(clearForward: false)
- })
- .keyboardShortcut(.defaultAction)
- .onSubmit {
- performGopherRequest()
- }
- Spacer()
- }
- HStack {
- Spacer()
- Button {
- performGopherRequest(host:"gopher.navan.dev",port: 70,selector: "/")
- } label: {
- Label("Home", systemImage: "house")
- .labelStyle(.iconOnly)
- }
- Spacer()
- Button {
- if let curNode = backwardStack.popLast() {
- forwardStack.append(curNode)
- if let prevNode = backwardStack.popLast() {
- performGopherRequest(host: prevNode.host, port: prevNode.port, selector: prevNode.selector, clearForward: false)
- }
- }
- } label: {
- Label("Back", systemImage: "chevron.left")
- .labelStyle(.iconOnly)
- }
- .disabled(backwardStack.count < 2)
- Spacer()
- Button {
- if let nextNode = forwardStack.popLast() {
- //backwardStack.append(nextNode)
- performGopherRequest(host: nextNode.host, port: nextNode.port, selector: nextNode.selector, clearForward: false)
- }
- } label: {
- Label("Forward", systemImage: "chevron.right")
- .labelStyle(.iconOnly)
- }
- .disabled(forwardStack.isEmpty)
- Spacer()
- }
+ }
+ }
+ }
+ .background(Color.white)
+ .cornerRadius(10)
+ .sheet(isPresented: $showSearchInput) {
+ if let index = selectedSearchItem, gopherItems.indices.contains(index) {
+ let searchItem = gopherItems[index]
+ SearchInputView(
+ host: searchItem.host,
+ port: searchItem.port,
+ selector: searchItem.selector,
+ searchText: $searchText,
+ onSearch: { query in
+ performGopherRequest(
+ host: searchItem.host, port: searchItem.port,
+ selector: "\(searchItem.selector)\t\(query)")
+ showSearchInput = false
}
- #else
- HStack(spacing: 10) {
- HStack {
- Spacer()
- Button {
- performGopherRequest(host:"gopher.navan.dev",port: 70,selector: "/")
- } label: {
- Label("Home", systemImage: "house")
- .labelStyle(.iconOnly)
- }
-
- Button {
- if let curNode = backwardStack.popLast() {
- forwardStack.append(curNode)
- if let prevNode = backwardStack.popLast() {
- performGopherRequest(host: prevNode.host, port: prevNode.port, selector: prevNode.selector, clearForward: false)
- }
- }
- } label: {
- Label("Back", systemImage: "chevron.left")
- .labelStyle(.iconOnly)
- }
- .disabled(backwardStack.count < 2)
-
- Button {
- if let nextNode = forwardStack.popLast() {
- //backwardStack.append(nextNode)
- performGopherRequest(host: nextNode.host, port: nextNode.port, selector: nextNode.selector, clearForward: false)
- }
- } label: {
- Label("Forward", systemImage: "chevron.right")
- .labelStyle(.iconOnly)
- }
- .disabled(forwardStack.isEmpty)
-
-
- TextField("Enter a URL", text: $url)
-#if !os(OSX)
- .keyboardType(.URL)
- .autocapitalization(.none)
-#endif
- .padding(10)
- Spacer()
- }
- //.background(Color.white)
- .cornerRadius(30)
-
- Button("Go", action: {
- performGopherRequest(clearForward: false)
- })
- .keyboardShortcut(.defaultAction)
- .onSubmit {
- performGopherRequest()
- }
- Spacer()
+ )
+ } else {
+
+ VStack {
+ Text("Weird bug. Please Dismiss -> Press Go -> Try Again")
+ Button("Dismiss") {
+ self.showSearchInput = false
+ }
+ }
+
+ }
+ }
+ } else {
+ Spacer()
+ Text("Welcome to iGopher Browser")
+ Spacer()
+ }
+ #if os(iOS)
+ VStack {
+ HStack(spacing: 10) {
+ HStack {
+ Spacer()
+
+ TextField("Enter a URL", text: $url)
+ #if !os(OSX)
+ .keyboardType(.URL)
+ .autocapitalization(.none)
+ #endif
+ .padding(10)
+ Spacer()
+ }
+ //.background(Color.white)
+ .cornerRadius(30)
+
+ Button(
+ "Go",
+ action: {
+ performGopherRequest(clearForward: false)
+ }
+ )
+ .keyboardShortcut(.defaultAction)
+ .onSubmit {
+ performGopherRequest()
+ }
+ Spacer()
+ }
+ HStack {
+ Spacer()
+ Button {
+ performGopherRequest(host: "gopher.navan.dev", port: 70, selector: "/")
+ } label: {
+ Label("Home", systemImage: "house")
+ .labelStyle(.iconOnly)
+ }
+ Spacer()
+ Button {
+ if let curNode = backwardStack.popLast() {
+ forwardStack.append(curNode)
+ if let prevNode = backwardStack.popLast() {
+ performGopherRequest(
+ host: prevNode.host, port: prevNode.port, selector: prevNode.selector,
+ clearForward: false)
+ }
+ }
+ } label: {
+ Label("Back", systemImage: "chevron.left")
+ .labelStyle(.iconOnly)
+ }
+ .disabled(backwardStack.count < 2)
+ Spacer()
+ Button {
+ if let nextNode = forwardStack.popLast() {
+ //backwardStack.append(nextNode)
+ performGopherRequest(
+ host: nextNode.host, port: nextNode.port, selector: nextNode.selector,
+ clearForward: false)
+ }
+ } label: {
+ Label("Forward", systemImage: "chevron.right")
+ .labelStyle(.iconOnly)
+ }
+ .disabled(forwardStack.isEmpty)
+ Spacer()
+ }
+ }
+ #else
+ HStack(spacing: 10) {
+ HStack {
+ Spacer()
+ Button {
+ performGopherRequest(host: "gopher.navan.dev", port: 70, selector: "/")
+ } label: {
+ Label("Home", systemImage: "house")
+ .labelStyle(.iconOnly)
+ }
+
+ Button {
+ if let curNode = backwardStack.popLast() {
+ forwardStack.append(curNode)
+ if let prevNode = backwardStack.popLast() {
+ performGopherRequest(
+ host: prevNode.host, port: prevNode.port, selector: prevNode.selector,
+ clearForward: false)
+ }
+ }
+ } label: {
+ Label("Back", systemImage: "chevron.left")
+ .labelStyle(.iconOnly)
+ }
+ .disabled(backwardStack.count < 2)
+
+ Button {
+ if let nextNode = forwardStack.popLast() {
+ //backwardStack.append(nextNode)
+ performGopherRequest(
+ host: nextNode.host, port: nextNode.port, selector: nextNode.selector,
+ clearForward: false)
}
+ } label: {
+ Label("Forward", systemImage: "chevron.right")
+ .labelStyle(.iconOnly)
+ }
+ .disabled(forwardStack.isEmpty)
+
+ TextField("Enter a URL", text: $url)
+ #if !os(OSX)
+ .keyboardType(.URL)
+ .autocapitalization(.none)
#endif
+ .padding(10)
+ Spacer()
}
- }
- .onChange(of: selectedNode) {
- if let node = selectedNode {
- performGopherRequest(host: node.host, port: node.port, selector: node.selector)
+ //.background(Color.white)
+ .cornerRadius(30)
+
+ Button(
+ "Go",
+ action: {
+ performGopherRequest(clearForward: false)
+ }
+ )
+ .keyboardShortcut(.defaultAction)
+ .onSubmit {
+ performGopherRequest()
}
- }
+ Spacer()
+ }
+ #endif
+ }
+ }
+ .onChange(of: selectedNode) {
+ if let node = selectedNode {
+ performGopherRequest(host: node.host, port: node.port, selector: node.selector)
+ }
+ }
+ }
+
+ private func performGopherRequest(
+ host: String = "", port: Int = -1, selector: String = "", clearForward: Bool = true
+ ) {
+ // TODO: Remove getHostandPort call here, and call it before calling performGopherRequest
+ print("recieved ", host, port, selector)
+ var res = getHostAndPort(from: self.url)
+
+ if host != "" {
+ res.host = host
+ if selector != "" {
+ res.selector = selector
+ } else {
+ res.selector = ""
+ }
}
-
- private func performGopherRequest(host: String = "", port: Int = -1, selector: String = "", clearForward: Bool = true) {
- // TODO: Remove getHostandPort call here, and call it before calling performGopherRequest
- print("recieved ", host, port, selector)
- var res = getHostAndPort(from: self.url)
-
- if host != "" {
- res.host = host
- if selector != "" {
- res.selector = selector
+
+ if port != -1 {
+ res.port = port
+ }
+
+ self.url = "\(res.host):\(res.port)\(res.selector)"
+
+ client.sendRequest(to: res.host, port: res.port, message: "\(res.selector)\r\n") { result in
+ switch result {
+ case .success(let resp):
+ //print(resp)
+ var newNode = GopherNode(
+ host: res.host, port: res.port, selector: selector, item: nil,
+ children: convertToHostNodes(resp))
+ backwardStack.append(newNode)
+ if clearForward {
+ forwardStack.removeAll()
+ }
+ print(newNode.selector)
+ if let index = self.hosts.firstIndex(where: { $0.host == res.host && $0.port == res.port })
+ {
+ // TODO: Handle case where first link visited is a subdirectory, should the sidebar auto fetch the rest?
+ print("parent already exists")
+ //hosts[index] = newNode
+ hosts[index].children = hosts[index].children?.map { child in
+ if child.selector == newNode.selector {
+ newNode.message = child.message
+ return newNode
} else {
- res.selector = ""
+ return child
}
+ }
+
+ } else {
+ newNode.selector = "/"
+ hosts.append(newNode)
+ print("created new")
}
-
- if port != -1 {
- res.port = port
- }
-
-
-
- self.url = "\(res.host):\(res.port)\(res.selector)"
-
- client.sendRequest(to: res.host, port: res.port, message: "\(res.selector)\r\n") { result in
- switch result {
- case .success(let resp):
- //print(resp)
- var newNode = GopherNode(host: res.host, port: res.port, selector: selector, item: nil, children: convertToHostNodes(resp))
- backwardStack.append(newNode)
- if clearForward {
- forwardStack.removeAll()
- }
- print(newNode.selector)
- if let index = self.hosts.firstIndex(where: { $0.host == res.host && $0.port == res.port }) {
- // TODO: Handle case where first link visited is a subdirectory, should the sidebar auto fetch the rest?
- print("parent already exists")
- //hosts[index] = newNode
- hosts[index].children = hosts[index].children?.map { child in
- if child.selector == newNode.selector {
- newNode.message = child.message
- return newNode
- } else {
- return child
- }
- }
-
- } else {
- newNode.selector = "/"
- hosts.append(newNode)
- print("created new")
- }
- self.gopherItems = resp
-
-
- case .failure(let error):
- print("Error \(error)")
- var item = gopherItem(rawLine: "Error \(error)")
- item.message = "Error \(error)"
- self.gopherItems = [item]
- }
- }
+ self.gopherItems = resp
+
+ case .failure(let error):
+ print("Error \(error)")
+ var item = gopherItem(rawLine: "Error \(error)")
+ item.message = "Error \(error)"
+ self.gopherItems = [item]
+ }
}
-
- private func convertToHostNodes(_ responseItems: [gopherItem]) -> [GopherNode] {
- var returnItems: [GopherNode] = []
- responseItems.forEach { item in
- if item.parsedItemType != .info {
- returnItems.append(GopherNode(host: item.host, port: item.port, selector: item.selector, message: item.message, item: item, children: nil))
- //print("found: \(item.message)")
- }
- }
- return returnItems
+ }
+
+ private func convertToHostNodes(_ responseItems: [gopherItem]) -> [GopherNode] {
+ var returnItems: [GopherNode] = []
+ responseItems.forEach { item in
+ if item.parsedItemType != .info {
+ returnItems.append(
+ GopherNode(
+ host: item.host, port: item.port, selector: item.selector, message: item.message,
+ item: item, children: nil))
+ //print("found: \(item.message)")
+ }
}
+ return returnItems
+ }
}