Compare commits

...

91 Commits

Author SHA1 Message Date
mrusme 38ec68e179
Merge pull request #77 from mrusme/dependabot/go_modules/golang.org/x/net-0.23.0
Bump golang.org/x/net from 0.17.0 to 0.23.0
2 months ago
dependabot[bot] b16fa8b982
Bump golang.org/x/net from 0.17.0 to 0.23.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2 months ago
mrusme e8ce6e92f4
Merge pull request #76 from mrusme/dependabot/go_modules/github.com/quic-go/quic-go-0.42.0
Bump github.com/quic-go/quic-go from 0.37.7 to 0.42.0
3 months ago
dependabot[bot] d100dbcb8b
Bump github.com/quic-go/quic-go from 0.37.7 to 0.42.0
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.37.7 to 0.42.0.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.37.7...v0.42.0)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
3 months ago
マリウス 67eb587b59
Re-added Radicle 3 months ago
mrusme c982502cfb
Merge pull request #75 from mrusme/dependabot/go_modules/google.golang.org/protobuf-1.33.0
Bump google.golang.org/protobuf from 1.30.0 to 1.33.0
3 months ago
dependabot[bot] 0f04f1f0ed
Bump google.golang.org/protobuf from 1.30.0 to 1.33.0
Bumps google.golang.org/protobuf from 1.30.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
4 months ago
mrusme 909cf957d0
Merge pull request #74 from mrusme/dependabot/go_modules/github.com/quic-go/quic-go-0.37.7
Bump github.com/quic-go/quic-go from 0.33.0 to 0.37.7
6 months ago
dependabot[bot] 9176d14b82
Bump github.com/quic-go/quic-go from 0.33.0 to 0.37.7
Bumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.33.0 to 0.37.7.
- [Release notes](https://github.com/quic-go/quic-go/releases)
- [Changelog](https://github.com/quic-go/quic-go/blob/master/Changelog.md)
- [Commits](https://github.com/quic-go/quic-go/compare/v0.33.0...v0.37.7)

---
updated-dependencies:
- dependency-name: github.com/quic-go/quic-go
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
mrusme 0c6049a768
Merge pull request #73 from mrusme/dependabot/go_modules/golang.org/x/crypto-0.17.0
Bump golang.org/x/crypto from 0.14.0 to 0.17.0
6 months ago
dependabot[bot] 6e89062339
Bump golang.org/x/crypto from 0.14.0 to 0.17.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0.
- [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
6 months ago
mrusme a1118a14d6
Merge pull request #72 from mrusme/dependabot/go_modules/golang.org/x/image-0.10.0
Bump golang.org/x/image from 0.5.0 to 0.10.0
8 months ago
dependabot[bot] c01d08179d
Bump golang.org/x/image from 0.5.0 to 0.10.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.5.0 to 0.10.0.
- [Commits](https://github.com/golang/image/compare/v0.5.0...v0.10.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
mrusme 36854a3f19
Merge pull request #71 from mrusme/dependabot/go_modules/google.golang.org/grpc-1.56.3
Bump google.golang.org/grpc from 1.53.0 to 1.56.3
8 months ago
dependabot[bot] 1eebf0daca
Bump google.golang.org/grpc from 1.53.0 to 1.56.3
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.53.0 to 1.56.3.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.53.0...v1.56.3)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
8 months ago
mrusme 6454de3813
Merge pull request #70 from mrusme/dependabot/go_modules/golang.org/x/net-0.17.0
Bump golang.org/x/net from 0.10.0 to 0.17.0
8 months ago
dependabot[bot] 20840ee918
Bump golang.org/x/net from 0.10.0 to 0.17.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.10.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.10.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
9 months ago
mrusme 5eee1c9b72
Merge pull request #68 from mrusme/dependabot/go_modules/github.com/libp2p/go-libp2p-0.27.8
Bump github.com/libp2p/go-libp2p from 0.26.4 to 0.27.8
11 months ago
mrusme 81e2344c32
Merge branch 'master' into dependabot/go_modules/github.com/libp2p/go-libp2p-0.27.8 11 months ago
mrusme dbec3d8ade
Merge pull request #63 from mrusme/dependabot/go_modules/golang.org/x/image-0.5.0
Bump golang.org/x/image from 0.0.0-20191206065243-da761ea9ff43 to 0.5.0
11 months ago
mrusme c4109b986f
Merge branch 'master' into dependabot/go_modules/golang.org/x/image-0.5.0 11 months ago
dependabot[bot] e4d41bec39
Bump github.com/libp2p/go-libp2p from 0.26.4 to 0.27.8
Bumps [github.com/libp2p/go-libp2p](https://github.com/libp2p/go-libp2p) from 0.26.4 to 0.27.8.
- [Release notes](https://github.com/libp2p/go-libp2p/releases)
- [Changelog](https://github.com/libp2p/go-libp2p/blob/master/CHANGELOG.md)
- [Commits](https://github.com/libp2p/go-libp2p/compare/v0.26.4...v0.27.8)

---
updated-dependencies:
- dependency-name: github.com/libp2p/go-libp2p
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
11 months ago
mrusme 4759f8bdd7
Merge pull request #67 from mrusme/dependabot/go_modules/google.golang.org/grpc-1.53.0
Bump google.golang.org/grpc from 1.50.1 to 1.53.0
12 months ago
dependabot[bot] 8e03fb977d
Bump google.golang.org/grpc from 1.50.1 to 1.53.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.50.1 to 1.53.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.50.1...v1.53.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
12 months ago
マリウス 51df3b2735
Updated Go version 1 year ago
マリウス 95edfeb29e
Removed Radicle
... because they can't seem to figure things out and change things over
and over and over again, breaking essentially everything for everyone.
It's sad.
1 year ago
マリウス a4a4047a02
Upgraded to latest go-orbit-db, fixed dependency 1 year ago
マリウス 65bcf85bb2
Fixed README.md git clone 1 year ago
dependabot[bot] ccfc019403
Bump golang.org/x/image from 0.0.0-20191206065243-da761ea9ff43 to 0.5.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.0.0-20191206065243-da761ea9ff43 to 0.5.0.
- [Release notes](https://github.com/golang/image/releases)
- [Commits](https://github.com/golang/image/commits/v0.5.0)

---
updated-dependencies:
- dependency-name: golang.org/x/image
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
mrusme e2475a7655
Merge pull request #62 from mrusme/dependabot/go_modules/golang.org/x/net-0.7.0
Bump golang.org/x/net from 0.4.0 to 0.7.0
1 year ago
dependabot[bot] 7f4fad4ae0
Bump golang.org/x/net from 0.4.0 to 0.7.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.4.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
mrusme 7621d0063b
Merge pull request #61 from mrusme/dependabot/go_modules/github.com/ipld/go-ipld-prime-0.19.0
Bump github.com/ipld/go-ipld-prime from 0.18.0 to 0.19.0
1 year ago
dependabot[bot] 2939a90c48
Bump github.com/ipld/go-ipld-prime from 0.18.0 to 0.19.0
Bumps [github.com/ipld/go-ipld-prime](https://github.com/ipld/go-ipld-prime) from 0.18.0 to 0.19.0.
- [Release notes](https://github.com/ipld/go-ipld-prime/releases)
- [Changelog](https://github.com/ipld/go-ipld-prime/blob/master/CHANGELOG.md)
- [Commits](https://github.com/ipld/go-ipld-prime/compare/v0.18.0...v0.19.0)

---
updated-dependencies:
- dependency-name: github.com/ipld/go-ipld-prime
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
mrusme 6829deb60f
Merge pull request #59 from mrusme/dependabot/go_modules/github.com/ipfs/go-unixfsnode-1.5.2
Bump github.com/ipfs/go-unixfsnode from 1.4.0 to 1.5.2
1 year ago
mrusme d0f25dc520
Merge pull request #58 from mrusme/dependabot/go_modules/github.com/ipfs/go-bitfield-1.1.0
Bump github.com/ipfs/go-bitfield from 1.0.0 to 1.1.0
1 year ago
dependabot[bot] 1adaa0b447
Bump github.com/ipfs/go-unixfsnode from 1.4.0 to 1.5.2
Bumps [github.com/ipfs/go-unixfsnode](https://github.com/ipfs/go-unixfsnode) from 1.4.0 to 1.5.2.
- [Release notes](https://github.com/ipfs/go-unixfsnode/releases)
- [Commits](https://github.com/ipfs/go-unixfsnode/compare/v1.4.0...v1.5.2)

---
updated-dependencies:
- dependency-name: github.com/ipfs/go-unixfsnode
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
dependabot[bot] 5ca3a0ce29
Bump github.com/ipfs/go-bitfield from 1.0.0 to 1.1.0
Bumps [github.com/ipfs/go-bitfield](https://github.com/ipfs/go-bitfield) from 1.0.0 to 1.1.0.
- [Release notes](https://github.com/ipfs/go-bitfield/releases)
- [Commits](https://github.com/ipfs/go-bitfield/compare/v1.0.0...v1.1.0)

---
updated-dependencies:
- dependency-name: github.com/ipfs/go-bitfield
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
mrusme 86d9dfde4e
Merge pull request #57 from Frederic-Zhou/master
Remove redundant  `if err!=nil`
1 year ago
Frederic ede24e837c Remove redundant `if err!=nil` 1 year ago
mrusme 3d91a442f7
Merge pull request #56 from Frederic-Zhou/master
Some code optimizations
1 year ago
Frederic 5214ed206b init(..) return error of ..Subscribe(..) & others 1 year ago
mrusme e011152ffc
Merge pull request #54 from mrusme/dependabot/go_modules/github.com/ipfs/go-merkledag-0.8.1
Bump github.com/ipfs/go-merkledag from 0.6.0 to 0.8.1
1 year ago
dependabot[bot] be07b22fdf
Bump github.com/ipfs/go-merkledag from 0.6.0 to 0.8.1
Bumps [github.com/ipfs/go-merkledag](https://github.com/ipfs/go-merkledag) from 0.6.0 to 0.8.1.
- [Release notes](https://github.com/ipfs/go-merkledag/releases)
- [Commits](https://github.com/ipfs/go-merkledag/compare/v0.6.0...v0.8.1)

---
updated-dependencies:
- dependency-name: github.com/ipfs/go-merkledag
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
mrusme 9d22fb980c
Merge pull request #53 from mrusme/dependabot/go_modules/github.com/ipld/go-codec-dagpb-1.5.0
Bump github.com/ipld/go-codec-dagpb from 1.4.1 to 1.5.0
1 year ago
dependabot[bot] 46e9d59090
Bump github.com/ipld/go-codec-dagpb from 1.4.1 to 1.5.0
Bumps [github.com/ipld/go-codec-dagpb](https://github.com/ipld/go-codec-dagpb) from 1.4.1 to 1.5.0.
- [Release notes](https://github.com/ipld/go-codec-dagpb/releases)
- [Commits](https://github.com/ipld/go-codec-dagpb/compare/v1.4.1...v1.5.0)

---
updated-dependencies:
- dependency-name: github.com/ipld/go-codec-dagpb
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
1 year ago
マリウス e425fc2d51
Updated to go-orbit-db v1.19.1 2 years ago
マリウス a1de04d46c
Updated README.md 2 years ago
マリウス 305a075614
Upgraded to orbit 1.18.0 and kubo 0.16 2 years ago
マリウス dad27bc85d
Added heading 2 years ago
マリウス ad3e9870c5
Updated README.md 2 years ago
マリウス 66c712a9fd
Updated README.md 2 years ago
マリウス f34d744bde
Updated workflow 2 years ago
マリウス b3233c949b
Updated dependencies 2 years ago
マリウス ff8f116e27
Updated README 2 years ago
マリウス 161fd7e0a7
Added connectivity information 2 years ago
マリウス 04de863299
Adjusted context, fixed #46, fixed #47 2 years ago
マリウス 69064d9df2
Removed player gimick
Didn't hear back from Poolsuite, so I'm removing this easter-egg.
2 years ago
マリウス f78a01cdd9
Updated Go version to 1.18, fixed #44 2 years ago
マリウス 537da5529e
Updated README.md 2 years ago
マリウス a007acb5a9
Updated .gitignore 2 years ago
マリウス f142aad7e6
Upgraded to go-orbit-db 1.17.1, fixed issues 2 years ago
マリウス 5ef5fe5c1f
Updated to go-version: 1.18 2 years ago
マリウス 6eb9ce7f0e
Added FUNDING.yml 2 years ago
マリウス f9c3786e99
Updated README.md 2 years ago
マリウス 3c9d5d047c
Removed android 2 years ago
mrusme 59edd4abd2
Merge pull request #41 from mrusme/go-orbit-db_upgrade
go-orbit-db upgrade
2 years ago
マリウス b0371b59ee
Refactored events according to https://github.com/berty/go-orbit-db/issues/100 2 years ago
マリウス 8802d55663
Updated README.md 2 years ago
マリウス d7bd0412ed
Addd code of conduct 2 years ago
マリウス 77f75108db
Updated README.md 2 years ago
マリウス 87813e3daa
Updated go quic dep for 1.18, updated README 2 years ago
マリウス d77e3f6823
Updated to go-orbit-db v1.16.0 2 years ago
マリウス af396ba602
Tried update to go-orbit-db- v1.16.0 2 years ago
マリウス 06a7c87258
go-orbit-db upgrade 2 years ago
マリウス e39c05adb9
Added android to goreleaser 2 years ago
マリウス 04ada9eb9e
Removed plan9 2 years ago
マリウス 7d2202880e
Upgraded to go-orbit-db v1.14.1, fixed #38 2 years ago
マリウス 078b3164ab
Replaced tab with space, fixed #40 2 years ago
マリウス c89a201b78
Fixed #36, added From: in editor view 2 years ago
mrusme 3d97580a25
Merge pull request #37 from mprimi/master
Add help and shortcuts reference view
2 years ago
Marco Primi 28ff3032bb Add help screen, currently showing default shortcuts
Hitting '?' brings up a modal with default shortcuts, for quick 
reference.
Also does a little refactoring in the code where default shortcuts are 
declared.

Known issue: anyone that has run SH84 before will have shortcuts loaded 
from config file and the new '?' command will be ignored. Addressing 
this is beyond the scope of this change.

Known issue: custom shortcuts are not displayed in help, only the 
default which may not correspond to the actual user configuration.
2 years ago
マリウス 21e6e02902
Fixed quote highlighting for empty lines 2 years ago
マリウス d5c6e0f14d
Added output to make loading more visible 2 years ago
マリウス 6f22c3cacf
Implemented ID and PubKey 2 years ago
マリウス 51a79a3dce
Implemented sorting by latest reply in thread 2 years ago
マリウス a9643b47b3
Fixed highlight issue on last line of quote 2 years ago
mrusme 7739400b63
Merge pull request #34 from mprimi/master
Refactor main screen layout using nested grids
2 years ago
Marco Primi 4d0e561aff Refactor main screen layout using nested grids
Simplify the main layout by creating sub-grids in each row of the 
existing grid.
This allows each row to have independent column layout.

Within each grid the placement is straighforward and can be more easily 
adjusted.

One visible change is that the main pane sizes are now relative, so they 
adjust based on the terminal width and height (whereas before they were 
fixed regardless of terminal size).
2 years ago
マリウス 63b4ce4db6
Added PGP meta filter 2 years ago
マリウス e3740cc651
Updated README.md 2 years ago
マリウス 0435efd200
Implemented views for articles list, documented 2 years ago

@ -0,0 +1 @@
custom: ["https://github.com/mrusme#support"]

@ -10,15 +10,15 @@ jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: 1.17
go-version: 1.20
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
uses: goreleaser/goreleaser-action@v3
with:
distribution: goreleaser
version: latest

1
.gitignore vendored

@ -3,3 +3,4 @@
/orbit*.db
/newsgroups
.gitsigners

@ -9,7 +9,8 @@ builds:
- netbsd
- openbsd
- freebsd
- plan9
# - plan9
# - android
- windows
goarch:
- 386
@ -28,6 +29,7 @@ builds:
goarch: arm64
- goos: freebsd
goarm: arm64
- goos: plan0
- goos: plan9
goarm: arm64

@ -0,0 +1,7 @@
Code of Conduct
---------------
If at anytime you choose to do something that a rational person of average
intelligence could reasonably consider your actions as "Being a dick", you are
in violation of this code of conduct.

@ -1,13 +1,16 @@
Superhighway84
--------------
[![Superhighway84](superhighway84.jpeg)](superhighway84.png)
```
===============================================================================
INTERACTIVE ASYNC / FULL DUPLEX
INTERACTIVE ASYNC / FULL DUPLEX
===============================================================================
Dial Up To 19.2 Kbps
Dial Up To 19.2 Kbps
with
with
_ _ _ __ ____ __ _ __ ___ ____
/ / / // / __/_ _____ ___ ____/ / (_)__ _/ / _ _____ ___ __( _ )/ / /
@ -15,13 +18,13 @@
/ / / // /___/\_,_/ .__/\__/_/ /_//_/_/\_, /_//_/__,__/\_,_/\_, /\___/ /_/
/_/ /___/ /___/
::: USENET-INSPIRED DECENTRALIZED INTERNET DISCUSSION SYSTEM :::
::: UNCENSORABLE USENET-INSPIRED DECENTRALIZED INTERNET DISCUSSION SYSTEM :::
The V.H.S. (Very High Speed) Superhighway84 platform is more than just the
fastest decentralized, USENET-inspired communications platform available. It is
also the first one to be based on the latest IPFS technology available today!
The V.H.S. (Very High Speed) Superhighway84 platform is more than just the
fastest decentralized, uncensorable, USENET-inspired communications platform
available. It is also the first one to be based on the latest
IPFS technology available today!
Superhighway84 offers the most spectacular features under the Spectrum.
@ -31,42 +34,102 @@ fastest decentralized, USENET-inspired communications platform available. It is
Long Haul Satellite Operation
Network Diagnostics
Fallback Mode
And More!
And More!
The Superhighway84 modern decentralized internet discussion system.
It should cost a lot more than $0.
The Superhighway84 modern, uncensorable,
decentralized internet discussion system.
It should cost a lot more than $0.
```
![Screenshot](screenshot01.png)
Superhighway84 is an open source, terminal-based, IPFS-powered, USENET-inspired,
uncensorable, decentralized peer-to-peer internet discussion system with retro
aesthetics.
[More info here.](https://xn--gckvb8fzb.com/superhighway84/)
## Installation
### Prerequisites
Download the [kubo 0.16
release](https://github.com/ipfs/kubo/releases/tag/v0.16.0) and unpack it:
```sh
$ tar -xzf ./kubo_*.tar.gz
```
INSTALLATION
------------
If you haven't used IPFS so far, initialize the IPFS repository using the
following command:
Clone this repository and run:
```sh
$ ./kubo/ipfs init
```
$ go build .
If you had used IPFS an already have an IPFS repository in place, either
(re)move it from `~/.ipfs` or make sure to `export IPFS_PATH` before running the
`ipfs init` command, e.g.:
The binary will be available at ./superhighway84 and can be moved wherever you
please.
```sh
$ export IPFS_PATH=~/.ipfs-sh84
$ ./go-ipfs/ipfs init
```
### From Release
Download the [latest
release](https://github.com/mrusme/superhighway84/releases/latest) and unpack
it:
```sh
$ tar -xzf ./superhighway84_*.tar.gz
$ ./superhighway84
```
If you don't have IPFS installed already, make sure to do so in order to be able
to initialize your IPFS repository:
If you initialized the IPFS repo under in a custom location, you need to prefix
`IPFS_PATH`:
https://docs.ipfs.io/install/command-line/
```sh
$ IPFS_PATH=~/.ipfs-sh84 ./superhighway84
```
The binary `superhighway84` can be moved wherever you please.
### From Source
Clone this repository
The IPFS repository can be initialized using the following command:
- from [GitHub](https://github.com/mrusme/superhighway84)
```sh
$ git clone git@github.com:mrusme/superhighway84.git
```
- from
[Radicle](https://app.radicle.xyz/nodes/seed.radicle.garden/rad:z4JkpNjyUemfCeU85iqssNEukoBn1/)
```sh
$ rad clone rad:z4JkpNjyUemfCeU85iqssNEukoBn1
```
$ ipfs init
Then cd into the cloned directory and run:
```sh
$ go build .
```
The binary will be available at ./superhighway84 and can be moved wherever you
please.
RUNNING
-------
## Running
First, check ulimit -n and verify that it's at a reasonable amount. IPFS
requires it to be large enough (>= 2048) in order to work properly over time.
@ -76,7 +139,9 @@ those flimsy MacBooks, older hardware, a Raspberry or a low-memory VPS it is
advisable to set the previously created IPFS repository to the `lowpower`
profile.
```sh
$ ipfs config profile apply lowpower
```
This should help with CPU usage, file descriptors and the amount of network
connections. While during the startup period you might still see peers peaking
@ -85,25 +150,20 @@ and 300 peers.
Afterwards you can simply launch the binary:
$ ./superhighway84
```sh
$ superhighway84
```
A setup wizard will help you with initial configuration. Please make sure to
have at least HOME and EDITOR exported in your environment.
In case you would like to use a dedicated ipfs repository for Superhighway84,
you will have to export a different IPFS_PATH and make sure it was initialized
beforehand:
$ export IPFS_PATH=~/.ipfs-sh84
$ ipfs init
$ superhighway84
In case you're intending to run the official IPFS daemon and Superhighway84 in
parallel, be sure to adjust the ports in their respective IPFS repos (e.g.
~/.ipfs and ~/.ipfs-sh84) so that they won't utilize the same port numbers.
The ports 4001, 5001 and 8080 are relevant and should be adjusted to something
other for every new repo/IPFS node that will run in parallel, e.g.:
`~/.ipfs` and `~/.ipfs-sh84`) so that they won't utilize the same port numbers.
The ports `4001`, `5001` and `8080` are relevant and should be adjusted to
something other for every new repo/IPFS node that will run in parallel, e.g.:
```json
"Addresses": {
"Swarm": [
"/ip4/0.0.0.0/tcp/4002",
@ -116,8 +176,9 @@ other for every new repo/IPFS node that will run in parallel, e.g.:
"API": "/ip4/127.0.0.1/tcp/5002",
"Gateway": "/ip4/127.0.0.1/tcp/8081"
},
```
NOTE: When running Superhighway84 for the first time it might seem like it's
**NOTE**: When running Superhighway84 for the first time it might seem like it's
"hanging" at the command prompt. Usually it isn't hanging but rather searching
for peer it can connect to in order to synchronize the database. Depending on
how many people are online, this process might take _some time_, please be
@ -125,11 +186,65 @@ patient.
USAGE
-----
## Connectivity
If you're having trouble connecting to the IPFS network that might be due to
your network setup. Please try the IPFS `AutoRelay` feature in such a case:
```sh
$ ipfs config --json Swarm.RelayClient.Enabled true
```
More information on this can be found here:
https://github.com/ipfs/kubo/blob/master/docs/experimental-features.md#autorelay
## Configuration
Superhighway84 will guide you through the basic configuration on its first run.
The configuration is stored at the path that you specified in the setup wizard.
After it was successfully created, it can be adjusted manually and will take
effect on the next launch of Superhighway84.
Configuration options that might be of interest:
```
ArticlesListView =
The view to be used for the articles lit. Possible values:
0 - threaded view, latest thread at the top
1 - list view, latest article at the top
[Profile]
From =
The identifier that is being shown when posting an article, e.g. your name,
username or email that you'd like to display
Organization =
An optional organization that you'd like to display affiliation with
[Shortcuts]
The shortcuts for navigating Superhighway84, can be reset to its defaults by
simply removing the whole [Shortcuts] block and launching Superhighway84
The structure is as following:
`<key code> = "event"`
The key codes can be looked up under the following link:
https://pkg.go.dev/github.com/gdamore/tcell/v2#Key
For simple ASCII characters use their ASCII code, e.g. `114` for the character
`r`.
```
## Usage
The default keyboard shortcuts are:
```
C-r: Refresh
C-h: Focus groups list
C-l, C-k: Focus articles list
@ -144,40 +259,98 @@ C-l, C-k: Focus articles list
CR: Select item in list
n: Publish new article
r: Reply to selected article
```
However, you are free to customize these within your configuration file, under
the section `Shortcuts`. The structure is as following:
the section `Shortcuts`.
### Submit Article
When submitting a new article or a reply to an article, the $EDITOR is launched
in which a document with a specific structure will be visible. This structure
consists of the HEADER, a SEPARATOR and the BODY and looks like this:
```
Subject: This is the subject of the article
Newsgroup: test.sandbox
= = = = = =
This is the multiline
body of the article
```
The HEADER contains all headers that are required for an article to be
submitted. These are:
`<key code> = "event"`
- `Subject:`\
The subject of the article that will be shown in the articles list. The
subject must only contain of printable ASCII characters.
The key codes can be looked up under the following link:
- `Newsgroup:`\
The newsgroup under which the article will be submitted, this can
either be an existing group or a new group. Please try to follow
the convention when creating new groups.
The newsgroup must only contain of printable ASCII characters.
https://pkg.go.dev/github.com/gdamore/tcell/v2#Key
The SEPARATOR contains of 6 equal signs and 5 spaces, alternating each
other, followed by a new line.
For simple ASCII characters use their ASCII code, e.g. `114` for the character
`r`.
The BODY can contain of multiline text.
KNOWN LIMITATIONS
-----------------
## Known Limitations
- The OrbitDB that Superhighway84 uses is a public database, meaning everyone
can alter its data. Since its using a standard _docstore_, PUT and DELETE
events can alter existing data. This issue will be solved in the future by
customizing the store to ignore these types of events.
- Probably plenty more that have yet to been found...
- Superhighway84 is bound to the version of IPFS that Berty decides to support
for go-orbit-db. go-orbit-db updates, on the other hand, seem to introduce
breaking changes from time to time, which are hard to debug as someone without
in-depth knowledge nor documentation. Since Superhighway84 is pretty much a
one-man-show it would be quite challenging to fork go-orbit-db in order to
keep it up to date with IPFS and make its interface more stable. Unfortunately
there doesn't seem to be an alternative to Berty's go-orbit-db as of right
now, so Superhighway84 is basically stuck with it.
If you happen to know your way around IPFS and maybe even go-orbit-db, and
would like to support this project, please get in touch!
- If you have a newer IPFS version installed than the one used by
Superhighway84, please make sure to **not upgrade** the IPFS_REPO that
Superhighway84 is using. Otherwise you will get an error when starting
Superhighway84 that will tell you that there is an IPFS repository mismatch:
```
> panic: Your programs version (11) is lower than your repos (12).
```
CREDITS
-------
If this should be the case, please follow the instructions provided here:
- Superhighway84 name, code and graphics by mrusme
https://github.com/mrusme
https://github.com/mrusme/superhighway84/issues/42#issuecomment-1100582472
- Logo backdrop by Swift
https://twitter.com/Swift_1_2/status/1114865117533888512
- If you encounter the following issue your IPFS repo version might be older
than what Superhighway84 is using:
```
> panic: ipfs repo needs migration
```
In this case you might want to follow the IPFS migration guide here:
https://github.com/ipfs/fs-repo-migrations/blob/master/run.md
Alternatively use the same IPFS version as used by Superhighway84 to
initialize a dedicated Superhighway84 repository. Please refer to the
INSTALLATION part for how to do so.
## Credits
- Superhighway84 name, code and graphics by [mrusme](https://github.com/mrusme)
- Logo backdrop by
[Swift](https://twitter.com/Swift_1_2/status/1114865117533888512)
```

10
cache/cache.go vendored

@ -1,22 +1,22 @@
package cache
import (
"encoding/json"
"encoding/json"
"github.com/mrusme/superhighway84/models"
"github.com/tidwall/buntdb"
"github.com/mrusme/superhighway84/models"
"github.com/tidwall/buntdb"
)
type Cache struct {
db *buntdb.DB
dbPath string
dbPath string
}
func NewCache(dbPath string) (*Cache, error) {
var err error
cache := new(Cache)
cache.dbPath = dbPath
cache.dbPath = dbPath
cache.db, err = buntdb.Open(cache.dbPath)
if err != nil {
return nil, err

@ -1,17 +0,0 @@
//go:build !poolsuite
package common
type Player struct {
}
func NewPlayer() (*Player) {
player := new(Player)
return player
}
func (p *Player) Play() {
return
}

@ -1,47 +0,0 @@
//go:build poolsuite
package common
import(
"github.com/mrusme/go-poolsuite"
)
type Player struct {
Poolsuite *poolsuite.Poolsuite
poolsuiteLoaded bool
poolsuitePlaying bool
}
func NewPlayer() (*Player) {
player := new(Player)
player.Poolsuite = poolsuite.NewPoolsuite()
player.poolsuiteLoaded = false
player.poolsuitePlaying = false
return player
}
func (p *Player) poolsuitePlay() {
p.Poolsuite.Play(
p.Poolsuite.GetRandomTrackFromPlaylist(
p.Poolsuite.GetRandomPlaylist(),
),
func() { p.poolsuitePlay() },
)
}
func (p *Player) Play() {
if p.poolsuiteLoaded == false {
p.poolsuiteLoaded = true
p.Poolsuite.Load()
}
if p.poolsuitePlaying == false {
p.poolsuitePlay()
p.poolsuitePlaying = true
} else {
p.Poolsuite.PauseResume()
p.poolsuitePlaying = false
}
}

@ -1,17 +1,17 @@
package config
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/BurntSushi/toml"
"github.com/gdamore/tcell/v2"
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/BurntSushi/toml"
"github.com/gdamore/tcell/v2"
)
type ConfigProfile struct {
@ -37,7 +37,7 @@ type Config struct {
ConnectionString string
CachePath string // Deprecated, should be removed soon
DatabaseCachePath string
DatabaseCachePath string
ProgramCachePath string
Logfile string
@ -45,6 +45,9 @@ type Config struct {
Profile ConfigProfile
Shortcuts map[string]string
ShortcutsReference string
ArticlesListView int8
}
func LoadConfig() (*Config, error) {
@ -87,28 +90,50 @@ func LoadConfig() (*Config, error) {
}
func (cfg *Config) LoadDefaults() (error) {
if len(cfg.Shortcuts) == 0 {
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlQ), 10)] = "quit"
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlR), 10)] = "refresh"
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlH), 10)] = "focus-groups"
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlL), 10)] = "focus-articles"
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlK), 10)] = "focus-articles"
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlJ), 10)] = "focus-preview"
cfg.Shortcuts[strconv.FormatInt(int64('n'), 10)] = "article-new"
cfg.Shortcuts[strconv.FormatInt(int64('r'), 10)] = "article-reply"
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyCtrlA), 10)] = "article-mark-all-read"
cfg.Shortcuts[strconv.FormatInt(int64('h'), 10)] = "additional-key-left"
cfg.Shortcuts[strconv.FormatInt(int64('j'), 10)] = "additional-key-down"
cfg.Shortcuts[strconv.FormatInt(int64('k'), 10)] = "additional-key-up"
cfg.Shortcuts[strconv.FormatInt(int64('l'), 10)] = "additional-key-right"
shortcutDefaults := []struct{
key tcell.Key
command string
keyAltText string
} {
{tcell.KeyCtrlQ, "quit", "C-q"},
{tcell.KeyCtrlR, "refresh", "C-r"},
{tcell.KeyCtrlH, "focus-groups", "C-h"},
{tcell.KeyCtrlL, "focus-articles", "C-l"},
{tcell.KeyCtrlK, "focus-articles", "C-k"},
{tcell.KeyCtrlJ, "focus-preview", "C-j"},
{tcell.KeyCtrlA, "article-mark-all-read", "C-a"},
{tcell.Key('n'), "article-new", ""},
{tcell.Key('r'), "article-reply", ""},
{tcell.Key('h'), "additional-key-left", ""},
{tcell.Key('j'), "additional-key-down", ""},
{tcell.Key('k'), "additional-key-up", ""},
{tcell.Key('l'), "additional-key-right", ""},
{tcell.Key('g'), "additional-key-home", ""},
{tcell.Key('G'), "additional-key-end", ""},
{tcell.Key('?'), "help", ""},
}
cfg.Shortcuts[strconv.FormatInt(int64('g'), 10)] = "additional-key-home"
cfg.Shortcuts[strconv.FormatInt(int64('G'), 10)] = "additional-key-end"
var sb strings.Builder
for _, shortcut := range shortcutDefaults {
keyText := string(shortcut.key)
if shortcut.keyAltText != "" {
keyText = shortcut.keyAltText
}
sb.WriteString(fmt.Sprintf("%s - %s\n", keyText, shortcut.command))
}
cfg.ShortcutsReference = sb.String()
cfg.Shortcuts[strconv.FormatInt(int64(tcell.KeyF8), 10)] = "play"
if len(cfg.Shortcuts) == 0 {
for _, shortcut := range shortcutDefaults {
cfg.Shortcuts[strconv.FormatInt(int64(shortcut.key), 10)] = shortcut.command
}
}
return cfg.Persist()
}
@ -127,10 +152,10 @@ func (cfg *Config) Persist() (error) {
func (cfg *Config) WasSetup() (bool) {
if cfg.DatabaseCachePath == "" ||
cfg.ProgramCachePath == "" ||
cfg.ProgramCachePath == "" ||
cfg.ConnectionString == "" ||
cfg.Logfile == "" ||
cfg.Profile.From == "" {
cfg.Profile.From == "" {
return false
}
@ -141,9 +166,9 @@ func (cfg *Config) Setup() (error) {
fmt.Printf("\nSUPERHIGHWAY84\n\nInitial Setup\n-------------\n\n")
defaultConnectionString := "/orbitdb/bafyreifdpagppa7ve45odxuvudz5snbzcybwyfer777huckl4li4zbc5k4/superhighway84"
if cfg.ConnectionString != "" {
defaultConnectionString = cfg.ConnectionString
}
if cfg.ConnectionString != "" {
defaultConnectionString = cfg.ConnectionString
}
fmt.Printf("Database connection string [%s]: ", defaultConnectionString)
fmt.Scanln(&cfg.ConnectionString)
if strings.TrimSpace(cfg.ConnectionString) == "" {
@ -156,10 +181,10 @@ func (cfg *Config) Setup() (error) {
}
defaultDatabaseCachePath := filepath.Join(cacheDir, "superhighway84", "database")
// Migration step from old CachePath to new DatabaseCachePath
if cfg.CachePath != "" {
defaultDatabaseCachePath = cfg.CachePath
}
// Migration step from old CachePath to new DatabaseCachePath
if cfg.CachePath != "" {
defaultDatabaseCachePath = cfg.CachePath
}
fmt.Printf("Database cache path [%s]: ", defaultDatabaseCachePath)
fmt.Scanln(&cfg.DatabaseCachePath)
if strings.TrimSpace(cfg.DatabaseCachePath) == "" {
@ -168,12 +193,12 @@ func (cfg *Config) Setup() (error) {
os.MkdirAll(filepath.Dir(cfg.DatabaseCachePath), 0755)
defaultProgramCachePath := filepath.Join(cacheDir, "superhighway84", "program")
// Migration step from old CachePath to new DatabaseCachePath
if cfg.CachePath != "" {
// If the previous CachePath was used, the folder already contains the
// OrbitDB, hence we need to find a different place
defaultProgramCachePath = filepath.Join(cacheDir, "superhighway84.program")
}
// Migration step from old CachePath to new DatabaseCachePath
if cfg.CachePath != "" {
// If the previous CachePath was used, the folder already contains the
// OrbitDB, hence we need to find a different place
defaultProgramCachePath = filepath.Join(cacheDir, "superhighway84.program")
}
fmt.Printf("Program cache path [%s]: ", defaultProgramCachePath)
fmt.Scanln(&cfg.ProgramCachePath)
if strings.TrimSpace(cfg.ProgramCachePath) == "" {
@ -182,9 +207,9 @@ func (cfg *Config) Setup() (error) {
os.MkdirAll(filepath.Dir(cfg.ProgramCachePath), 0755)
defaultLogfile := filepath.Join(cacheDir, "superhighway84.log")
if cfg.Logfile != "" {
defaultLogfile = cfg.Logfile
}
if cfg.Logfile != "" {
defaultLogfile = cfg.Logfile
}
fmt.Printf("Logfile path [%s]: ", defaultLogfile)
fmt.Scanln(&cfg.Logfile)
if strings.TrimSpace(cfg.Logfile) == "" {
@ -195,19 +220,19 @@ func (cfg *Config) Setup() (error) {
fmt.Printf("\nProfile information\n-------------------\n\n")
defaultProfileFrom := fmt.Sprintf("%s@localhost", os.Getenv("USER"))
if cfg.Profile.From != "" {
defaultProfileFrom = cfg.Profile.From
}
if cfg.Profile.From != "" {
defaultProfileFrom = cfg.Profile.From
}
fmt.Printf("From [%s]: ", defaultProfileFrom)
fmt.Scanln(&cfg.Profile.From)
if strings.TrimSpace(cfg.Profile.From) == "" {
cfg.Profile.From = defaultProfileFrom
}
defaultProfileOrganization := ""
if cfg.Profile.Organization != "" {
defaultProfileOrganization = cfg.Profile.Organization
}
defaultProfileOrganization := ""
if cfg.Profile.Organization != "" {
defaultProfileOrganization = cfg.Profile.Organization
}
fmt.Printf("Organization [%s]: ", defaultProfileOrganization)
fmt.Scanln(&cfg.Profile.Organization)

@ -4,17 +4,19 @@ import (
"context"
"sort"
"sync"
"time"
orbitdb "berty.tech/go-orbit-db"
"berty.tech/go-orbit-db/accesscontroller"
"berty.tech/go-orbit-db/events"
"berty.tech/go-orbit-db/iface"
"berty.tech/go-orbit-db/stores"
"berty.tech/go-orbit-db/stores/documentstore"
config "github.com/ipfs/go-ipfs-config"
"github.com/ipfs/go-ipfs/core"
icore "github.com/ipfs/interface-go-ipfs-core"
"github.com/libp2p/go-libp2p-core/peer"
config "github.com/ipfs/kubo/config"
"github.com/ipfs/kubo/core"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/event"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/mitchellh/mapstructure"
"go.uber.org/zap"
@ -23,72 +25,87 @@ import (
)
type Database struct {
ctx context.Context
ConnectionString string
URI string
CachePath string
Cache *cache.Cache
ctx context.Context
ConnectionString string
URI string
CachePath string
Cache *cache.Cache
Logger *zap.Logger
Logger *zap.Logger
IPFSNode *core.IpfsNode
IPFSCoreAPI icore.CoreAPI
IPFSNode *core.IpfsNode
IPFSCoreAPI icore.CoreAPI
OrbitDB orbitdb.OrbitDB
Store orbitdb.DocumentStore
StoreEventChan <-chan events.Event
OrbitDB orbitdb.OrbitDB
Store orbitdb.DocumentStore
Events event.Subscription
}
func (db *Database) init() (error) {
var err error
db.OrbitDB, err = orbitdb.NewOrbitDB(db.ctx, db.IPFSCoreAPI, &orbitdb.NewOrbitDBOptions{
Directory: &db.CachePath,
Logger: db.Logger,
})
if err != nil {
return err
}
ac := &accesscontroller.CreateAccessControllerOptions{
Access: map[string][]string{
"write": {
"*",
},
},
}
if err != nil {
return err
}
// addr, err := db.OrbitDB.DetermineAddress(db.ctx, db.Name, "docstore", &orbitdb.DetermineAddressOptions{})
// if err != nil {
// return err
// }
// db.URI = addr.String()
storetype := "docstore"
db.Store, err = db.OrbitDB.Docs(db.ctx, db.ConnectionString, &orbitdb.CreateDBOptions{
AccessController: ac,
StoreType: &storetype,
StoreSpecificOpts: documentstore.DefaultStoreOptsForMap("id"),
})
if err != nil {
return err
}
db.StoreEventChan = db.Store.Subscribe(db.ctx)
return nil
func (db *Database) init() error {
var err error
ctx := context.Background()
db.Logger.Debug("initializing NewOrbitDB ...")
db.OrbitDB, err = orbitdb.NewOrbitDB(ctx, db.IPFSCoreAPI, &orbitdb.NewOrbitDBOptions{
Directory: &db.CachePath,
Logger: db.Logger,
})
if err != nil {
return err
}
ac := &accesscontroller.CreateAccessControllerOptions{
Access: map[string][]string{
"write": {
"*",
},
},
}
// addr, err := db.OrbitDB.DetermineAddress(db.ctx, db.Name, "docstore", &orbitdb.DetermineAddressOptions{})
// if err != nil {
// return err
// }
// db.URI = addr.String()
storetype := "docstore"
db.Logger.Debug("initializing OrbitDB.Docs ...")
db.Store, err = db.OrbitDB.Docs(ctx, db.ConnectionString, &orbitdb.CreateDBOptions{
AccessController: ac,
StoreType: &storetype,
StoreSpecificOpts: documentstore.DefaultStoreOptsForMap("id"),
Timeout: time.Second * 600,
})
if err != nil {
return err
}
db.Logger.Debug("subscribing to EventBus ...")
db.Events, err = db.Store.EventBus().Subscribe(new(stores.EventReady))
return err
}
func (db *Database) GetOwnID() string {
return db.OrbitDB.Identity().ID
}
func(db *Database) connectToPeers() error {
func (db *Database) GetOwnPubKey() crypto.PubKey {
pubKey, err := db.OrbitDB.Identity().GetPublicKey()
if err != nil {
return nil
}
return pubKey
}
func (db *Database) connectToPeers() error {
var wg sync.WaitGroup
peerInfos, err := config.DefaultBootstrapPeers()
if err != nil {
return err
}
peerInfos, err := config.DefaultBootstrapPeers()
if err != nil {
return err
}
wg.Add(len(peerInfos))
for _, peerInfo := range peerInfos {
@ -96,10 +113,10 @@ func(db *Database) connectToPeers() error {
defer wg.Done()
err := db.IPFSCoreAPI.Swarm().Connect(db.ctx, *peerInfo)
if err != nil {
db.Logger.Debug("failed to connect", zap.String("peerID", peerInfo.ID.String()), zap.Error(err))
db.Logger.Error("failed to connect", zap.String("peerID", peerInfo.ID.String()), zap.Error(err))
} else {
db.Logger.Debug("connected!", zap.String("peerID", peerInfo.ID.String()))
}
db.Logger.Debug("connected!", zap.String("peerID", peerInfo.ID.String()))
}
}(&peerInfo)
}
wg.Wait()
@ -107,165 +124,186 @@ func(db *Database) connectToPeers() error {
}
func NewDatabase(
ctx context.Context,
dbConnectionString string,
dbCache string,
cch *cache.Cache,
logger *zap.Logger,
ctx context.Context,
dbConnectionString string,
dbCache string,
cch *cache.Cache,
logger *zap.Logger,
) (*Database, error) {
var err error
db := new(Database)
db.ctx = ctx
db.ConnectionString = dbConnectionString
db.CachePath = dbCache
db.Cache = cch
db.Logger = logger
defaultPath, err := config.PathRoot()
if err != nil {
return nil, err
}
var err error
db := new(Database)
db.ctx = ctx
db.ConnectionString = dbConnectionString
db.CachePath = dbCache
db.Cache = cch
db.Logger = logger
db.Logger.Debug("getting config root path ...")
defaultPath, err := config.PathRoot()
if err != nil {
return nil, err
}
if err := setupPlugins(defaultPath); err != nil {
db.Logger.Debug("setting up plugins ...")
if err := setupPlugins(defaultPath); err != nil {
return nil, err
}
db.IPFSNode, db.IPFSCoreAPI, err = createNode(ctx, defaultPath)
if err != nil {
return nil, err
}
db.Logger.Debug("creating IPFS node ...")
db.IPFSNode, db.IPFSCoreAPI, err = createNode(ctx, defaultPath)
if err != nil {
return nil, err
}
return db, nil
return db, nil
}
func (db *Database) Connect(onReady func(address string)) (error) {
var err error
// if db.Init {
err = db.init()
if err != nil {
return err
}
// } else {
// err = db.open()
// if err != nil {
// return err
// }
// }
func (db *Database) Connect(onReady func(address string)) error {
var err error
db.Logger.Info("connecting to peers ...")
// go func() {
err = db.connectToPeers()
if err != nil {
db.Logger.Debug("failed to connect: %s", zap.Error(err))
} else {
db.Logger.Debug("connected to peer!")
}
err = db.connectToPeers()
if err != nil {
db.Logger.Error("failed to connect: %s", zap.Error(err))
} else {
db.Logger.Debug("connected to peer!")
}
// }()
// log.Println(db.Store.ReplicationStatus().GetBuffered())
// log.Println(db.Store.ReplicationStatus().GetQueued())
// log.Println(db.Store.ReplicationStatus().GetProgress())
db.Logger.Info("running ...")
go func() {
for {
for ev := range db.StoreEventChan {
db.Logger.Debug("got event", zap.Any("event", ev))
switch ev.(type) {
case *stores.EventReady:
db.URI = db.Store.Address().String()
onReady(db.URI)
}
}
}
}()
err = db.Store.Load(db.ctx, -1)
if err != nil {
// TODO: clean up
return err
}
return nil
db.Logger.Info("initializing database connection ...")
// if db.Init {
err = db.init()
if err != nil {
db.Logger.Error("%s", zap.Error(err))
return err
}
// } else {
// err = db.open()
// if err != nil {
// return err
// }
// }
db.Logger.Info("running ...")
go func() {
for {
for ev := range db.Events.Out() {
db.Logger.Debug("got event", zap.Any("event", ev))
switch ev.(type) {
case stores.EventReady:
db.URI = db.Store.Address().String()
onReady(db.URI)
continue
}
}
}
}()
err = db.Store.Load(db.ctx, -1)
if err != nil {
db.Logger.Error("%s", zap.Error(err))
// TODO: clean up
return err
}
db.Logger.Debug("connect done")
return nil
}
func (db *Database) Disconnect() {
db.OrbitDB.Close()
db.Events.Close()
db.Store.Close()
db.OrbitDB.Close()
}
func (db *Database) SubmitArticle(article *models.Article) (error) {
entity, err := structToMap(*article)
if err != nil {
return err
}
entity["type"] = "article"
func (db *Database) SubmitArticle(article *models.Article) error {
entity, err := structToMap(*article)
if err != nil {
return err
}
entity["type"] = "article"
_, err = db.Store.Put(db.ctx, entity)
return err
_, err = db.Store.Put(db.ctx, entity)
return err
}
func (db *Database) GetArticleByID(id string) (models.Article, error) {
entity, err := db.Store.Get(db.ctx, id, &iface.DocumentStoreGetOptions{CaseInsensitive: false})
if err != nil {
return models.Article{}, err
}
var article models.Article
err = mapstructure.Decode(entity[0], &article)
if err != nil {
return models.Article{}, err
}
return article, nil
entity, err := db.Store.Get(db.ctx, id, &iface.DocumentStoreGetOptions{CaseInsensitive: false})
if err != nil {
return models.Article{}, err
}
var article models.Article
err = mapstructure.Decode(entity[0], &article)
if err != nil {
return models.Article{}, err
}
return article, nil
}
func (db *Database) ListArticles() ([]*models.Article, []*models.Article, error) {
var articles []*models.Article
var articlesMap map[string]*models.Article
articlesMap = make(map[string]*models.Article)
_, err := db.Store.Query(db.ctx, func(e interface{})(bool, error) {
entity := e.(map[string]interface{})
if entity["type"] == "article" {
var article models.Article
err := mapstructure.Decode(entity, &article)
if err == nil {
// TODO: Not sure why mapstructure won't convert this field and simply
// leave it ""
if entity["in-reply-to-id"] != nil {
article.InReplyToID = entity["in-reply-to-id"].(string)
}
db.Cache.LoadArticle(&article)
articles = append(articles, &article)
articlesMap[article.ID] = articles[(len(articles) - 1)]
}
return true, err
}
return false, nil
})
if err != nil {
return articles, nil, err
}
sort.SliceStable(articles, func(i, j int) bool {
return articles[i].Date > articles[j].Date
})
var articlesRoots []*models.Article
for i := 0; i < len(articles); i++ {
if articles[i].InReplyToID != "" {
if _, exist := articlesMap[articles[i].InReplyToID]; exist == true {
(*articlesMap[articles[i].InReplyToID]).Replies =
append((*articlesMap[articles[i].InReplyToID]).Replies, articles[i])
}
} else {
articlesRoots = append(articlesRoots, articles[i])
}
}
return articles, articlesRoots, nil
}
var articles []*models.Article
var articlesMap = make(map[string]*models.Article)
_, err := db.Store.Query(db.ctx, func(e interface{}) (bool, error) {
entity := e.(map[string]interface{})
if entity["type"] == "article" {
var article models.Article
err := mapstructure.Decode(entity, &article)
if err == nil {
// TODO: Not sure why mapstructure won't convert this field and simply
// leave it ""
if entity["in-reply-to-id"] != nil {
article.InReplyToID = entity["in-reply-to-id"].(string)
}
db.Cache.LoadArticle(&article)
articles = append(articles, &article)
articlesMap[article.ID] = articles[(len(articles) - 1)]
}
return true, err
}
return false, nil
})
if err != nil {
return articles, nil, err
}
sort.SliceStable(articles, func(i, j int) bool {
return articles[i].Date > articles[j].Date
})
var articlesRoots []*models.Article
for i := 0; i < len(articles); i++ {
if articles[i].InReplyToID != "" {
inReplyTo := articles[i].InReplyToID
if _, exist := articlesMap[inReplyTo]; exist {
(*articlesMap[inReplyTo]).Replies =
append((*articlesMap[inReplyTo]).Replies, articles[i])
(*articlesMap[inReplyTo]).LatestReply = articles[i].Date
continue
}
}
articlesRoots = append(articlesRoots, articles[i])
}
sort.SliceStable(articlesRoots, func(i, j int) bool {
iLatest := articlesRoots[i].LatestReply
if iLatest <= 0 {
iLatest = articlesRoots[i].Date
}
jLatest := articlesRoots[j].LatestReply
if jLatest <= 0 {
jLatest = articlesRoots[j].Date
}
return iLatest > jLatest
})
return articles, articlesRoots, nil
}

@ -7,12 +7,12 @@ import (
"path/filepath"
files "github.com/ipfs/go-ipfs-files"
"github.com/ipfs/go-ipfs/core"
"github.com/ipfs/go-ipfs/core/coreapi"
"github.com/ipfs/go-ipfs/core/node/libp2p"
"github.com/ipfs/go-ipfs/plugin/loader"
"github.com/ipfs/go-ipfs/repo/fsrepo"
icore "github.com/ipfs/interface-go-ipfs-core"
"github.com/ipfs/kubo/core"
"github.com/ipfs/kubo/core/coreapi"
"github.com/ipfs/kubo/core/node/libp2p"
"github.com/ipfs/kubo/plugin/loader"
"github.com/ipfs/kubo/repo/fsrepo"
"github.com/mitchellh/mapstructure"
)
@ -42,10 +42,10 @@ func createNode(ctx context.Context, repoPath string) (*core.IpfsNode, icore.Cor
nodeOptions := &core.BuildCfg{
Online: true,
Routing: libp2p.DHTClientOption, // DHTOption
Repo: repo,
ExtraOpts: map[string]bool{
"pubsub": true,
},
Repo: repo,
ExtraOpts: map[string]bool{
"pubsub": true,
},
}
node, err := core.NewNode(ctx, nodeOptions)
@ -53,12 +53,12 @@ func createNode(ctx context.Context, repoPath string) (*core.IpfsNode, icore.Cor
return nil, nil, err
}
coreAPI, err := coreapi.NewCoreAPI(node)
if err != nil {
return nil, nil, err
}
coreAPI, err := coreapi.NewCoreAPI(node)
if err != nil {
return nil, nil, err
}
return node, coreAPI, nil
return node, coreAPI, nil
}
func getUnixfsNode(path string) (files.Node, error) {
@ -76,13 +76,12 @@ func getUnixfsNode(path string) (files.Node, error) {
}
func structToMap(v interface{}) (map[string]interface{}, error) {
vMap := &map[string]interface{}{}
vMap := &map[string]interface{}{}
err := mapstructure.Decode(v, &vMap)
if err != nil {
return nil, err
}
err := mapstructure.Decode(v, &vMap)
if err != nil {
return nil, err
}
return *vMap, nil
return *vMap, nil
}

349
go.mod

@ -1,240 +1,235 @@
module github.com/mrusme/superhighway84
go 1.17
go 1.20
require (
berty.tech/go-orbit-db v1.13.2
github.com/ipfs/go-datastore v0.4.5
github.com/ipfs/go-filestore v0.0.3
github.com/ipfs/go-ipfs v0.9.1
github.com/ipfs/go-ipfs-config v0.14.0
github.com/ipfs/go-ipfs-keystore v0.0.2
github.com/libp2p/go-libp2p v0.14.3
github.com/libp2p/go-libp2p-core v0.8.5
berty.tech/go-orbit-db v1.22.0
github.com/BurntSushi/toml v1.2.1
github.com/eliukblau/pixterm v1.3.1
github.com/gdamore/tcell/v2 v2.6.0
github.com/go-playground/validator/v10 v10.12.0
github.com/google/uuid v1.3.0
github.com/ipfs/go-ipfs-files v0.3.0
github.com/ipfs/interface-go-ipfs-core v0.11.1
github.com/ipfs/kubo v0.19.0
github.com/libp2p/go-libp2p v0.27.8
github.com/mitchellh/mapstructure v1.5.0
github.com/rivo/tview v0.0.0-20230330183452-5796b0cd5c1f
github.com/tidwall/buntdb v1.2.10
go.uber.org/zap v1.24.0
)
require (
bazil.org/fuse v0.0.0-20200117225306-7b5117fecadc // indirect
berty.tech/go-ipfs-log v1.5.0 // indirect
berty.tech/go-ipfs-log v1.10.0 // indirect
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
github.com/BurntSushi/toml v0.4.1 // indirect
github.com/Stebalien/go-bitfield v0.0.1 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect
github.com/benbjohnson/clock v1.0.3 // indirect
github.com/benbjohnson/clock v1.3.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/btcsuite/btcd v0.21.0-beta // indirect
github.com/btcsuite/btcd v0.22.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/cheekybits/genny v1.0.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect
github.com/cskr/pubsub v1.0.2 // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/dgraph-io/badger v1.6.2 // indirect
github.com/dgraph-io/ristretto v0.0.2 // indirect
github.com/dgraph-io/ristretto v0.0.3 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/eliukblau/pixterm v1.3.1 // indirect
github.com/elastic/gosigar v0.14.2 // indirect
github.com/facebookgo/atomicfile v0.0.0-20151019160806-2de1f203e7d5 // indirect
github.com/faiface/beep v1.1.0 // indirect
github.com/flynn/noise v1.0.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell v1.4.0 // indirect
github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.9.0 // indirect
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-collections/go-datastructures v0.0.0-20150211160725-59788d5eb259 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/hajimehoshi/go-mp3 v0.3.0 // indirect
github.com/hajimehoshi/oto v0.7.1 // indirect
github.com/google/pprof v0.0.0-20230405160723-4a4c7d95572b // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/huin/goupnp v1.0.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.2 // indirect
github.com/huin/goupnp v1.1.0 // indirect
github.com/ipfs/bbloom v0.0.4 // indirect
github.com/ipfs/go-bitswap v0.3.4 // indirect
github.com/ipfs/go-block-format v0.0.3 // indirect
github.com/ipfs/go-blockservice v0.1.4 // indirect
github.com/ipfs/go-cid v0.0.7 // indirect
github.com/ipfs/go-cidutil v0.0.2 // indirect
github.com/ipfs/go-ds-badger v0.2.6 // indirect
github.com/ipfs/go-ds-flatfs v0.4.5 // indirect
github.com/ipfs/go-ds-leveldb v0.4.2 // indirect
github.com/ipfs/go-ds-measure v0.1.0 // indirect
github.com/ipfs/go-fs-lock v0.0.6 // indirect
github.com/ipfs/go-graphsync v0.8.0 // indirect
github.com/ipfs/go-ipfs-blockstore v0.1.6 // indirect
github.com/ipfs/go-bitfield v1.1.0 // indirect
github.com/ipfs/go-block-format v0.1.1 // indirect
github.com/ipfs/go-blockservice v0.5.0 // indirect
github.com/ipfs/go-cid v0.4.1 // indirect
github.com/ipfs/go-cidutil v0.1.0 // indirect
github.com/ipfs/go-datastore v0.6.0 // indirect
github.com/ipfs/go-delegated-routing v0.7.0 // indirect
github.com/ipfs/go-ds-badger v0.3.0 // indirect
github.com/ipfs/go-ds-flatfs v0.5.1 // indirect
github.com/ipfs/go-ds-leveldb v0.5.0 // indirect
github.com/ipfs/go-ds-measure v0.2.0 // indirect
github.com/ipfs/go-fetcher v1.6.1 // indirect
github.com/ipfs/go-filestore v1.2.0 // indirect
github.com/ipfs/go-fs-lock v0.0.7 // indirect
github.com/ipfs/go-graphsync v0.14.1 // indirect
github.com/ipfs/go-ipfs-blockstore v1.2.0 // indirect
github.com/ipfs/go-ipfs-chunker v0.0.5 // indirect
github.com/ipfs/go-ipfs-cmds v0.6.0 // indirect
github.com/ipfs/go-ipfs-delay v0.0.1 // indirect
github.com/ipfs/go-ipfs-ds-help v0.1.1 // indirect
github.com/ipfs/go-ipfs-exchange-interface v0.0.1 // indirect
github.com/ipfs/go-ipfs-exchange-offline v0.0.1 // indirect
github.com/ipfs/go-ipfs-files v0.0.8 // indirect
github.com/ipfs/go-ipfs-pinner v0.1.1 // indirect
github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect
github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect
github.com/ipfs/go-ipfs-exchange-offline v0.3.0 // indirect
github.com/ipfs/go-ipfs-keystore v0.1.0 // indirect
github.com/ipfs/go-ipfs-pinner v0.3.0 // indirect
github.com/ipfs/go-ipfs-posinfo v0.0.1 // indirect
github.com/ipfs/go-ipfs-pq v0.0.2 // indirect
github.com/ipfs/go-ipfs-provider v0.5.1 // indirect
github.com/ipfs/go-ipfs-routing v0.1.0 // indirect
github.com/ipfs/go-ipfs-pq v0.0.3 // indirect
github.com/ipfs/go-ipfs-provider v0.8.1 // indirect
github.com/ipfs/go-ipfs-routing v0.3.0 // indirect
github.com/ipfs/go-ipfs-util v0.0.2 // indirect
github.com/ipfs/go-ipld-cbor v0.0.5 // indirect
github.com/ipfs/go-ipld-format v0.2.0 // indirect
github.com/ipfs/go-ipld-git v0.0.4 // indirect
github.com/ipfs/go-ipns v0.1.0 // indirect
github.com/ipfs/go-ipld-cbor v0.0.6 // indirect
github.com/ipfs/go-ipld-format v0.4.0 // indirect
github.com/ipfs/go-ipld-git v0.1.1 // indirect
github.com/ipfs/go-ipld-legacy v0.1.1 // indirect
github.com/ipfs/go-ipns v0.3.0 // indirect
github.com/ipfs/go-libipfs v0.6.2 // indirect
github.com/ipfs/go-log v1.0.5 // indirect
github.com/ipfs/go-log/v2 v2.1.3 // indirect
github.com/ipfs/go-merkledag v0.3.2 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/ipfs/go-merkledag v0.10.0 // indirect
github.com/ipfs/go-metrics-interface v0.0.1 // indirect
github.com/ipfs/go-mfs v0.1.2 // indirect
github.com/ipfs/go-namesys v0.3.0 // indirect
github.com/ipfs/go-path v0.0.9 // indirect
github.com/ipfs/go-peertaskqueue v0.2.0 // indirect
github.com/ipfs/go-unixfs v0.2.5 // indirect
github.com/ipfs/go-verifcid v0.0.1 // indirect
github.com/ipfs/interface-go-ipfs-core v0.4.0 // indirect
github.com/ipld/go-codec-dagpb v1.2.0 // indirect
github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db // indirect
github.com/ipfs/go-mfs v0.2.1 // indirect
github.com/ipfs/go-namesys v0.7.0 // indirect
github.com/ipfs/go-path v0.3.1 // indirect
github.com/ipfs/go-peertaskqueue v0.8.1 // indirect
github.com/ipfs/go-unixfs v0.4.4 // indirect
github.com/ipfs/go-unixfsnode v1.5.2 // indirect
github.com/ipfs/go-verifcid v0.0.2 // indirect
github.com/ipld/edelweiss v0.2.0 // indirect
github.com/ipld/go-codec-dagpb v1.6.0 // indirect
github.com/ipld/go-ipld-prime v0.20.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect
github.com/jbenet/goprocess v0.1.4 // indirect
github.com/klauspost/compress v1.11.7 // indirect
github.com/klauspost/cpuid/v2 v2.0.4 // indirect
github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/libp2p/go-addr-util v0.0.2 // indirect
github.com/libp2p/go-buffer-pool v0.0.2 // indirect
github.com/klauspost/compress v1.16.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/koron/go-ssdp v0.0.4 // indirect
github.com/leodido/go-urn v1.2.2 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-cidranger v1.1.0 // indirect
github.com/libp2p/go-conn-security-multistream v0.2.1 // indirect
github.com/libp2p/go-doh-resolver v0.3.1 // indirect
github.com/libp2p/go-eventbus v0.2.1 // indirect
github.com/libp2p/go-flow-metrics v0.0.3 // indirect
github.com/libp2p/go-libp2p-asn-util v0.0.0-20200825225859-85005c6cf052 // indirect
github.com/libp2p/go-libp2p-autonat v0.4.2 // indirect
github.com/libp2p/go-libp2p-blankhost v0.2.0 // indirect
github.com/libp2p/go-libp2p-circuit v0.4.0 // indirect
github.com/libp2p/go-libp2p-connmgr v0.2.4 // indirect
github.com/libp2p/go-libp2p-discovery v0.5.1 // indirect
github.com/libp2p/go-libp2p-kad-dht v0.12.2 // indirect
github.com/libp2p/go-libp2p-kbucket v0.4.7 // indirect
github.com/libp2p/go-libp2p-loggables v0.1.0 // indirect
github.com/libp2p/go-libp2p-mplex v0.4.1 // indirect
github.com/libp2p/go-libp2p-nat v0.0.6 // indirect
github.com/libp2p/go-libp2p-netutil v0.1.0 // indirect
github.com/libp2p/go-libp2p-noise v0.2.0 // indirect
github.com/libp2p/go-libp2p-peerstore v0.2.7 // indirect
github.com/libp2p/go-libp2p-pnet v0.2.0 // indirect
github.com/libp2p/go-libp2p-pubsub v0.4.2 // indirect
github.com/libp2p/go-libp2p-pubsub-router v0.4.0 // indirect
github.com/libp2p/go-libp2p-quic-transport v0.11.2 // indirect
github.com/libp2p/go-libp2p-record v0.1.3 // indirect
github.com/libp2p/go-libp2p-routing-helpers v0.2.3 // indirect
github.com/libp2p/go-libp2p-swarm v0.5.0 // indirect
github.com/libp2p/go-libp2p-testing v0.4.0 // indirect
github.com/libp2p/go-libp2p-tls v0.1.3 // indirect
github.com/libp2p/go-libp2p-transport-upgrader v0.4.2 // indirect
github.com/libp2p/go-libp2p-xor v0.0.0-20200501025846-71e284145d58 // indirect
github.com/libp2p/go-libp2p-yamux v0.5.4 // indirect
github.com/libp2p/go-maddr-filter v0.1.0 // indirect
github.com/libp2p/go-mplex v0.3.0 // indirect
github.com/libp2p/go-msgio v0.0.6 // indirect
github.com/libp2p/go-nat v0.0.5 // indirect
github.com/libp2p/go-netroute v0.1.6 // indirect
github.com/libp2p/go-openssl v0.0.7 // indirect
github.com/libp2p/go-reuseport v0.0.2 // indirect
github.com/libp2p/go-reuseport-transport v0.0.4 // indirect
github.com/libp2p/go-sockaddr v0.1.1 // indirect
github.com/libp2p/go-stream-muxer-multistream v0.3.0 // indirect
github.com/libp2p/go-tcp-transport v0.2.4 // indirect
github.com/libp2p/go-ws-transport v0.4.0 // indirect
github.com/libp2p/go-yamux/v2 v2.2.0 // indirect
github.com/lucas-clemente/quic-go v0.21.2 // indirect
github.com/libp2p/go-doh-resolver v0.4.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
github.com/libp2p/go-libp2p-kad-dht v0.21.1 // indirect
github.com/libp2p/go-libp2p-kbucket v0.5.0 // indirect
github.com/libp2p/go-libp2p-pubsub v0.9.3 // indirect
github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-libp2p-routing-helpers v0.6.1 // indirect
github.com/libp2p/go-libp2p-xor v0.1.0 // indirect
github.com/libp2p/go-mplex v0.7.0 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.1.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
github.com/libp2p/go-reuseport v0.2.0 // indirect
github.com/libp2p/go-yamux/v4 v4.0.0 // indirect
github.com/libp2p/zeroconf/v2 v2.2.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/marten-seemann/qtls-go1-15 v0.1.5 // indirect
github.com/marten-seemann/qtls-go1-16 v0.1.4 // indirect
github.com/marten-seemann/qtls-go1-17 v0.1.0-rc.1 // indirect
github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/miekg/dns v1.1.41 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/miekg/dns v1.1.53 // indirect
github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect
github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/mrusme/go-poolsuite v0.0.0-20220102191132-9dd8514d3e05 // indirect
github.com/multiformats/go-base32 v0.0.3 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multiaddr v0.3.3 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.2.0 // indirect
github.com/multiformats/go-multiaddr v0.9.0 // indirect
github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect
github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect
github.com/multiformats/go-multiaddr-net v0.2.0 // indirect
github.com/multiformats/go-multibase v0.0.3 // indirect
github.com/multiformats/go-multicodec v0.2.0 // indirect
github.com/multiformats/go-multihash v0.0.15 // indirect
github.com/multiformats/go-multistream v0.2.2 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.4 // indirect
github.com/multiformats/go-multibase v0.2.0 // indirect
github.com/multiformats/go-multicodec v0.8.1 // indirect
github.com/multiformats/go-multihash v0.2.1 // indirect
github.com/multiformats/go-multistream v0.4.1 // indirect
github.com/multiformats/go-varint v0.0.7 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
github.com/opencontainers/runtime-spec v1.0.2 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/openzipkin/zipkin-go v0.4.0 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e // indirect
github.com/prometheus/client_golang v1.10.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.18.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/rivo/tview v0.0.0-20211202162923-2a6de950f73b // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/polydawn/refmt v0.89.0 // indirect
github.com/prometheus/client_golang v1.14.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/quic-go v0.42.0 // indirect
github.com/quic-go/webtransport-go v0.5.2 // indirect
github.com/raulk/go-watchdog v1.3.0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/samber/lo v1.36.0 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/tidwall/btree v1.1.0 // indirect
github.com/tidwall/buntdb v1.2.9 // indirect
github.com/tidwall/gjson v1.12.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
github.com/tidwall/btree v1.4.2 // indirect
github.com/tidwall/gjson v1.14.3 // indirect
github.com/tidwall/grect v0.1.4 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tidwall/rtred v0.1.2 // indirect
github.com/tidwall/tinyqueue v0.1.1 // indirect
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect
github.com/whyrusleeping/cbor-gen v0.0.0-20210219115102-f37d292932f2 // indirect
github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa // indirect
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/whyrusleeping/mdns v0.0.0-20190826153040-b9b60ed33aa9 // indirect
github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect
github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v0.20.0 // indirect
go.opentelemetry.io/otel/trace v0.20.0 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/dig v1.10.0 // indirect
go.uber.org/fx v1.13.1 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/zap v1.16.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.11.1 // indirect
go.opentelemetry.io/otel/exporters/jaeger v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.7.0 // indirect
go.opentelemetry.io/otel/exporters/zipkin v1.7.0 // indirect
go.opentelemetry.io/otel/sdk v1.11.1 // indirect
go.opentelemetry.io/otel/trace v1.11.1 // indirect
go.opentelemetry.io/proto/otlp v0.16.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/dig v1.16.1 // indirect
go.uber.org/fx v1.19.2 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go4.org v0.0.0-20200411211856-f5505b9728dd // indirect
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd // indirect
golang.org/x/image v0.0.0-20191206065243-da761ea9ff43 // indirect
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 // indirect
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781 // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.1 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/grpc v1.33.2 // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect
golang.org/x/image v0.10.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.9.1 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
google.golang.org/grpc v1.56.3 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
lukechampine.com/blake3 v1.1.7 // indirect
nhooyr.io/websocket v1.8.7 // indirect
)

1092
go.sum

File diff suppressed because it is too large Load Diff

@ -1,10 +1,10 @@
package models
import (
"time"
"time"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
"github.com/go-playground/validator/v10"
"github.com/google/uuid"
)
type Article struct {
@ -18,7 +18,9 @@ type Article struct {
Body string `mapstructure:"body" json:"-" validate:"required,min=3,max=524288"`
Replies []*Article `mapstructure:"-" json:"-" validate:"-"`
Read bool `mapstructure:"-" json:"read" validate:"-"`
LatestReply int64 `mapstructure:"-" json:"-" validate:"-"`
Read bool `mapstructure:"-" json:"read" validate:"-"`
}
func NewArticle() (*Article) {

@ -1,24 +1,24 @@
package main
import (
"context"
"embed"
"encoding/json"
"net/http"
"net/url"
"os"
"runtime"
"strings"
"time"
"log"
"github.com/mrusme/superhighway84/cache"
"github.com/mrusme/superhighway84/config"
"github.com/mrusme/superhighway84/database"
"github.com/mrusme/superhighway84/models"
"github.com/mrusme/superhighway84/tui"
"go.uber.org/zap"
"context"
"embed"
"encoding/json"
"net/http"
"net/url"
"os"
"runtime"
"strings"
"time"
"log"
"github.com/mrusme/superhighway84/cache"
"github.com/mrusme/superhighway84/config"
"github.com/mrusme/superhighway84/database"
"github.com/mrusme/superhighway84/models"
"github.com/mrusme/superhighway84/tui"
"go.uber.org/zap"
)
//go:embed superhighway84.jpeg
@ -32,7 +32,7 @@ func NewLogger(filename string) (*zap.Logger, error) {
})
}
cfg := zap.NewProductionConfig()
cfg := zap.NewDevelopmentConfig()
if runtime.GOOS == "windows" {
cfg.OutputPaths = []string{
"stdout",
@ -43,6 +43,7 @@ func NewLogger(filename string) (*zap.Logger, error) {
filename,
}
}
return cfg.Build()
}
@ -50,6 +51,7 @@ func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
log.Println("loading configuration ...")
cfg, err := config.LoadConfig()
if err != nil {
log.Panicln(err)
@ -58,11 +60,13 @@ func main() {
cfg.Setup()
}
log.Println("initializing logger ...")
logger, err := NewLogger(cfg.Logfile)
if err != nil {
log.Panicln(err)
}
log.Println("initializing cache ...")
cch, err := cache.NewCache(cfg.ProgramCachePath)
if err != nil {
log.Panicln(err)
@ -72,12 +76,14 @@ func main() {
var articles []*models.Article
var articlesRoots []*models.Article
log.Println("initializing TUI and loading database, please wait ...")
TUI := tui.Init(&EMBEDFS, cfg, cch, logger)
TUI.SetVersion(strings.TrimLeft(version, "v"), strings.TrimLeft(getLatestVersion(), "v") )
TUI.ArticlesDatasource = &articles
TUI.ArticlesRoots = &articlesRoots
log.Println("initializing database ...")
db, err := database.NewDatabase(ctx, cfg.ConnectionString, cfg.DatabaseCachePath, cch, logger)
if err != nil {
log.Panicln(err)
@ -86,16 +92,28 @@ func main() {
TUI.CallbackRefreshArticles = func() (error) {
articles, articlesRoots, err = db.ListArticles()
if err != nil {
logger.Error("%s", zap.Error(err))
}
return err
}
TUI.CallbackSubmitArticle = func(article *models.Article) (error) {
return db.SubmitArticle(article)
err := db.SubmitArticle(article)
if err != nil {
logger.Error("%s", zap.Error(err))
}
return err
}
log.Println("connecting database ...")
err = db.Connect(func(address string) {
TUI.Meta["myID"] = db.GetOwnID()
TUI.Meta["myPubKey"] = db.GetOwnPubKey()
TUI.Views["mainscreen"].(*tui.Mainscreen).SetFooter(address)
articles, articlesRoots, _ = db.ListArticles()
time.Sleep(time.Second * 2)
TUI.SetView("mainscreen", true)
@ -115,6 +133,8 @@ func main() {
connections, err := db.IPFSCoreAPI.Swarm().Peers(context.Background())
if err == nil {
peers = len(connections)
} else {
logger.Error("%s", zap.Error(err))
}
TUI.SetStats(int64(peers), int64(bw.RateIn), int64(bw.RateOut), bw.TotalIn , bw.TotalOut)
time.Sleep(time.Second * 5)

@ -1,16 +1,16 @@
package tui
import (
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
"time"
"github.com/mrusme/superhighway84/models"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
"time"
"github.com/mrusme/superhighway84/models"
)
func MillisecondsToDate(ms int64) (string) {
@ -30,8 +30,8 @@ func (t *TUI) OpenArticle(article *models.Article, readOnly bool) (models.Articl
defer os.Remove(tmpFile.Name())
tmpContent := []byte(fmt.Sprintf(
"Subject: %s\nNewsgroup: %s\n= = = = = =\n%s",
article.Subject, article.Newsgroup, article.Body))
"Subject: %s\nNewsgroup: %s\nFrom: %s\n= = = = = =\n%s",
article.Subject, article.Newsgroup, article.From, article.Body))
if _, err = tmpFile.Write(tmpContent); err != nil {
return *article, err
}

@ -1,15 +1,15 @@
package tui
import (
"fmt"
"regexp"
"sort"
"strings"
"time"
"github.com/gdamore/tcell/v2"
"github.com/mrusme/superhighway84/models"
"github.com/rivo/tview"
"fmt"
"regexp"
"sort"
"strings"
"time"
"github.com/gdamore/tcell/v2"
"github.com/mrusme/superhighway84/models"
"github.com/rivo/tview"
)
var HEADER_LOGO =
@ -34,6 +34,15 @@ const (
COLOR_SUBJECT_READ = "white"
)
var HELP_TEMPLATE =
`
HELP!
Default shortcuts:
%s
`
type GroupMapEntry struct {
Index int
}
@ -60,6 +69,8 @@ type Mainscreen struct {
ArticlesList []*models.Article
MarkTimer *time.Timer
ArticlesListView int8
}
func(t *TUI) NewMainscreen() (*Mainscreen) {
@ -130,20 +141,31 @@ func(t *TUI) NewMainscreen() (*Mainscreen) {
mainscreen.Footer.SetBorder(false).
SetBorderPadding(0, 0, 1, 1)
mainscreen.Canvas = tview.NewGrid().
SetRows(5, 0, 0, 1).
SetColumns(30, 0, 14).
SetBorders(false).
AddItem(mainscreen.Header, 0, 0, 1, 2, 0, 0, false).
AddItem(mainscreen.Stats, 0, 2, 1, 1, 0, 0, false).
AddItem(mainscreen.Info, 3, 0, 1, 1, 0, 0, false).
AddItem(mainscreen.Footer, 3, 1, 1, 2, 0, 0, false)
mainscreen.Canvas.
AddItem(mainscreen.Groups, 1, 0, 2, 1, 0, 0, false).
AddItem(mainscreen.Articles, 1, 1, 1, 2, 0, 0, false).
AddItem(mainscreen.Preview, 2, 1, 1, 2, 0, 0, false)
topRowGrid := tview.NewGrid().
SetColumns(30, 0, 14).
AddItem(mainscreen.Header, 0, 0, 1, 2, 0, 0, false).
AddItem(mainscreen.Stats, 0, 2, 1, 1, 0, 0, false)
midRowGrid := tview.NewGrid().
SetColumns(-1, -5). // Group takes ~1/5 of the horizontal space available
SetRows(-2, -3). // Preview is ~1/3 bigger than Articles
AddItem(mainscreen.Groups, 0, 0, 2, 1, 0, 0, false).
AddItem(mainscreen.Articles, 0, 1, 1, 1, 0, 0, false).
AddItem(mainscreen.Preview, 1, 1, 1, 1, 0, 0, false)
bottomRowGrid := tview.NewGrid().
SetColumns(5, 0, 0).
AddItem(mainscreen.Info, 0, 0, 1, 1, 0, 0, false).
AddItem(mainscreen.Footer, 0, 1, 1, 2, 0, 0, false)
mainscreen.Canvas = tview.NewGrid().
SetRows(5, 0, 1).
SetBorders(false).
AddItem(topRowGrid, 0, 0, 1, 1, 0, 0, false).
AddItem(midRowGrid, 1, 0, 1, 1, 0, 0, false).
AddItem(bottomRowGrid, 2, 0, 1, 1, 0, 0, false)
mainscreen.ArticlesListView = mainscreen.T.Config.ArticlesListView
return mainscreen
}
@ -206,7 +228,7 @@ func (mainscreen *Mainscreen) GetDefaultFocus() (tview.Primitive) {
return mainscreen.Articles
}
func(mainscreen *Mainscreen) addNodeToArticlesList(level int, articlesNode *[]*models.Article, selectedGroup int, previousGroupsList []string) {
func(mainscreen *Mainscreen) addNodeToArticlesList(view int8, level int, articlesNode *[]*models.Article, selectedGroup int, previousGroupsList []string) {
// fmt.Fprintf(os.Stderr, "%s Node has %d items\n", strings.Repeat(" ", level * 3), len(*articlesNode))
for i := 0; i < len(*articlesNode); i++ {
@ -219,7 +241,7 @@ func(mainscreen *Mainscreen) addNodeToArticlesList(level int, articlesNode *[]*m
article.Newsgroup == previousGroupsList[selectedGroup]) {
prefix := ""
if level > 0 {
if view == 0 && level > 0 {
if i < (len(*articlesNode) - 1) || len(article.Replies) > 0 {
prefix = "[gray]├[-]"
} else {
@ -228,7 +250,7 @@ func(mainscreen *Mainscreen) addNodeToArticlesList(level int, articlesNode *[]*m
}
prefixSub := " "
if len(article.Replies) > 0 || (level > 0 && i < (len(*articlesNode) - 1)) {
if view == 0 && (len(article.Replies) > 0 || (level > 0 && i < (len(*articlesNode) - 1))) {
prefixSub = "[gray]│[-]"
}
@ -254,8 +276,8 @@ func(mainscreen *Mainscreen) addNodeToArticlesList(level int, articlesNode *[]*m
), 0, nil)
mainscreen.ArticlesList = append(mainscreen.ArticlesList, article)
if len(article.Replies) > 0 {
mainscreen.addNodeToArticlesList((level + 1), &article.Replies, selectedGroup, previousGroupsList)
if view == 0 && len(article.Replies) > 0 {
mainscreen.addNodeToArticlesList(view, (level + 1), &article.Replies, selectedGroup, previousGroupsList)
}
}
@ -288,7 +310,14 @@ func(mainscreen *Mainscreen) Refresh() {
Index: 0,
}
mainscreen.addNodeToArticlesList(0, mainscreen.T.ArticlesRoots, selectedGroup, previousGroupsList)
var articlesSource *[]*models.Article
switch(mainscreen.ArticlesListView) {
case 0:
articlesSource = mainscreen.T.ArticlesRoots
case 1:
articlesSource = mainscreen.T.ArticlesDatasource
}
mainscreen.addNodeToArticlesList(mainscreen.ArticlesListView, 0, articlesSource, selectedGroup, previousGroupsList)
sort.Strings(mainscreen.GroupsList)
for idx, group := range mainscreen.GroupsList {
@ -344,6 +373,8 @@ func (mainscreen *Mainscreen) HandleInput(event *tcell.EventKey) (*tcell.EventKe
mainscreen.T.App.QueueEvent(tcell.NewEventKey(tcell.KeyHome, 0, tcell.ModNone))
case "additional-key-end":
mainscreen.T.App.QueueEvent(tcell.NewEventKey(tcell.KeyEnd, 0, tcell.ModNone))
case "help":
mainscreen.showHelp()
}
return event
@ -383,8 +414,19 @@ func(mainscreen *Mainscreen) selectHandler(item string)(func(int, string, string
}
func(mainscreen *Mainscreen) renderPreview(article *models.Article) {
m := regexp.MustCompile(`(?m)^> (.*)\n`)
body := m.ReplaceAllString(article.Body, "[gray]> $1[-]\n")
var m *regexp.Regexp
body := article.Body
// Removing GPG/PGP stuff until there is a prober validation for it
m = regexp.MustCompile(`(?m)^(> ){0,1}-----BEGIN PGP SIGNED MESSAGE-----\n(> ){0,1}Hash:(.*)(\n( >){0,1}){1,2}`)
body = m.ReplaceAllString(body, "")
m = regexp.MustCompile(`(?sm)^(> ){0,1}-----BEGIN PGP SIGNATURE-----.*-----END PGP SIGNATURE-----$`)
body = m.ReplaceAllString(body, "")
// End GPG/PGP stuff
m = regexp.MustCompile(`(?m)^>(.*)(\n){0,1}`)
body = m.ReplaceAllString(body, "[gray]> $1[-]\n")
mainscreen.Preview.SetText(fmt.Sprintf(
"[gray]Date:[-] [darkgray]%s[-]\n[gray]Newsgroup:[-] [darkgray]%s[-]\n\n\n%s",
@ -517,3 +559,9 @@ func(mainscreen *Mainscreen) replyToArticle(article *models.Article) {
return
}
func(mainscreen *Mainscreen) showHelp() {
helpMessage := fmt.Sprintf(HELP_TEMPLATE, mainscreen.T.Config.ShortcutsReference)
mainscreen.T.ShowHelpModal(helpMessage)
return
}

@ -1,13 +1,13 @@
package tui
import (
"bytes"
"fmt"
"image/color"
"bytes"
"fmt"
"image/color"
"github.com/eliukblau/pixterm/pkg/ansimage"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/eliukblau/pixterm/pkg/ansimage"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
@ -22,9 +22,9 @@ func(t *TUI) NewSplashscreen(logo *[]byte) (*Splashscreen) {
splashscreen.T = t
canvas := tview.NewTextView().
SetDynamicColors(true).
SetRegions(true).
SetWrap(true)
SetDynamicColors(true).
SetRegions(true).
SetWrap(true)
canvas.SetBorder(false)
canvas.Clear()
@ -54,7 +54,7 @@ func(splashscreen *Splashscreen) Refresh() {
return
}
// splashscreen.Canvas.Clear()
fmt.Fprint(splashscreen.Canvas, tview.TranslateANSI(logoImage.RenderExt(false, false)))
fmt.Fprint(splashscreen.Canvas, tview.TranslateANSI(logoImage.RenderExt(false, false)))
}
func (splashscreen *Splashscreen) HandleInput(event *tcell.EventKey) (*tcell.EventKey) {

@ -1,19 +1,18 @@
package tui
import (
"embed"
"log"
"strconv"
"time"
"unicode"
"github.com/gdamore/tcell/v2"
"github.com/mrusme/superhighway84/cache"
"github.com/mrusme/superhighway84/common"
"github.com/mrusme/superhighway84/config"
"github.com/mrusme/superhighway84/models"
"github.com/rivo/tview"
"go.uber.org/zap"
"embed"
"log"
"strconv"
"time"
"unicode"
"github.com/gdamore/tcell/v2"
"github.com/mrusme/superhighway84/cache"
"github.com/mrusme/superhighway84/config"
"github.com/mrusme/superhighway84/models"
"github.com/rivo/tview"
"go.uber.org/zap"
)
type TUI struct {
@ -40,8 +39,7 @@ type TUI struct {
Version string
VersionLatest string
// The fun starts here
Player *common.Player
Meta map[string]interface{}
}
type View interface {
@ -82,6 +80,8 @@ func Init(embedfs *embed.FS, cfg *config.Config, cch *cache.Cache, logger *zap.L
t.Stats = make(map[string]int64)
t.Meta = make(map[string]interface{})
logoBytes, err := embedfs.ReadFile("superhighway84.jpeg")
if err != nil {
log.Panicln(err)
@ -95,8 +95,6 @@ func Init(embedfs *embed.FS, cfg *config.Config, cch *cache.Cache, logger *zap.L
t.initInput()
// The fun stuff
t.Player = common.NewPlayer()
return t
}
@ -117,20 +115,17 @@ func (t *TUI) getInputEvent(event *tcell.EventKey) (string) {
}
func (t *TUI) initInput() {
t.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
t.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
action := t.getInputEvent(event)
switch action {
case "refresh":
switch action {
case "refresh":
t.RefreshMainscreen()
t.SetInfo(true)
t.App.Sync()
return nil
case "quit":
t.App.Stop()
return nil
case "play":
t.Player.Play()
case "quit":
t.App.Stop()
return nil
default:
if t.ModalVisible == true {
@ -147,8 +142,8 @@ func (t *TUI) initInput() {
} else {
return t.Views[t.ActiveView].HandleInput(event)
}
}
})
}
})
}
func (t *TUI) Launch() {
@ -247,6 +242,19 @@ func(t *TUI) ShowErrorModal(text string) {
})
}
func(t *TUI) ShowHelpModal(text string) {
t.ShowModal(
text,
map[string]ModalButton{
"Press any key to close": {
Rune: '*',
Callback: func() {
return
},
},
})
}
func (t *TUI) SetInfo(refresh bool) {
if refresh == true {
t.Views["mainscreen"].(*Mainscreen).SetInfo(map[string]string{

Loading…
Cancel
Save