Giter Site home page Giter Site logo

telephant's Introduction

Telephant

Latest Release GoDoc Build Status Go ReportCard

A lightweight but modern Mastodon client for the desktop, written in Go & QML.

telephant logo

Features

  • Live feed via Mastodon's Streaming API
  • Multi pane support
  • Linux/macOS/Windows (Android & iOS should be working, but aren't tested yet)
  • Media previews
  • Shortened URL resolving
  • System notifications
  • Direct messages
  • Multiple accounts (work-in-progress)
  • Support for more networks

Installation

Packages & Binaries

Ubuntu

Note that Telephant requires Qt >=5.12 installed. This means it currently doesn't support Ubuntu <19.04 or Linux Mint.

You need to install the following dependencies to run the Ubuntu binary:

apt install libqt5gui5 libqt5qml5 libqt5quickcontrols2-5 libqt5multimedia5-plugins \
            qml-module-qtquick2 qml-module-qtmultimedia qml-module-qtquick-layouts \
            qml-module-qtquick-controls qml-module-qtquick-controls2 \
            qml-module-qtquick-window2 qml-module-qtgraphicaleffects \
            qml-module-qtquick-dialogs qml-module-qt-labs-folderlistmodel \
            qml-module-qt-labs-settings

From Source

Make sure you have a working Go environment (Go 1.9 or higher is required). See the install instructions.

You will also need Qt5 >=5.12 and its development headers installed.

Dependencies (Ubuntu example)

apt-get --no-install-recommends install build-essential git libglib2.0-dev libglu1-mesa-dev libpulse-dev
apt-get --no-install-recommends install libqt*5-dev qt*5-dev qt*5-doc-html qml-module-qtquick*
apt-get install qml-module-qtmultimedia qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings

Building Telephant

export QT_PKG_CONFIG=true
go get -u -v -tags=no_env github.com/therecipe/qt/cmd/...
go get -d -u -v github.com/muesli/telephant
cd $(go env GOPATH)/src/github.com/muesli/telephant
$(go env GOPATH)/bin/qtdeploy build desktop .

Within a Docker Container

Follow the build instructions above, but instead of the last command, run:

$(go env GOPATH)/bin/qtdeploy -docker build linux

Run it

./deploy/linux/telephant

telephant Screenshot

telephant's People

Contributors

calmbit avatar gsora avatar masterofthetiger avatar muesli avatar tachiniererin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

telephant's Issues

macOS: support retina display

When I am using the highDPI display setting on my Macbook, Icons and Profile pictures look blurry compared to the text and menus.

Screenshot 2019-05-14 at 10 08 00

Scrolling problem

When scrolling through the columns and then letting go the pointer (I use a TrackPoint on a ThinkPad), probably more than half the time the view "bounces" back, like I have reached the bottom of the column, even though i have not. This is regardless of Media Content within the columns

Replies don't load when opening posts

Title explains it all. Only the post being opened is loaded. No replies, nor the posts above it in the case of opening a reply to another post, ever get shown.

Tested using the prebuilt binary on Xubuntu 18.04.

Edit: Specifically, this seems to happen with posts from instances other than the one the account is on. Loading up my own thread works fine, as does other same-instance communication.

Toots not posting with privacy "unlisted" and hashtags

Ok, so the combination of hashtag + unlisted privacy makes no sense, but I stumbled across this behavior accidentally.

Steps to reproduce:

  1. Hit New Post button.
  2. Enter "#test"
  3. Click Post.

If privacy is set to "unlisted" by default, the toot will not post. Bringing up the New Post window again shows the same contents as before ("#test").

Empty timeline

And now after fixing #42 (which does work, btw, so thank you), I've run into another issue. The window is now being created, but nothing is showing in the timeline. (See attached screenshot.)
Telephant's empty timeline

It's clear by the terminal output that it's fetching the individual statuses, but for whatever reason, it's not making it to the GUI.

Edit: I should add that there are no error messages in the terminal output this time.

Add installing + configuring pkg-config to README instructions

When following the README compilation instructions without having Go or anything related already installed before, the last step (build) will fail because of a missing "pkg-config" installation, at least on Windows 10.

Error:

cmd="pkg-config --modversion Qt5Core" dir= env= error="exec: \"pkg-config\": executable file not found in %PATH%" name=cgo.LinuxPkgConfig_modVersion

Once downloaded and added to path it seems to complain about not finding the Qt5Core package here as well, not sure if that is just me doing something wrong (e.g. faulty Qt installation).

Error:

cmd="pkg-config --modversion Qt5Core" dir= env= error="exit status 1" name=cgo.LinuxPkgConfig_modVersion
Package Qt5Core was not found in the pkg-config search path.
Perhaps you should add the directory containing 'Qt5Core.pc' to the PKG_CONFIG_PATH environment variable
No package 'Qt5Core' found`

If this is not actually a user error made by me, then I recommend adding notes on how to avoid this to the readme.

macOS: Quitting/Closing the app does not work properly

When I want to close telephant on macOS, the window disappears but the App still exists in the dock. Relaunching it does not work because it is in an "Not responding" state. (see Screenshot)

Screenshot 2019-05-14 at 10 19 21

Here are the logs I am getting in the terminal:

goroutine 1 [running, locked to thread]:
runtime.throw(0x445d4dd, 0x2d)
	/usr/local/go/src/runtime/panic.go:617 +0x72 fp=0xc0000dde80 sp=0xc0000dde50 pc=0x4031872
runtime.exitsyscall()
	/usr/local/go/src/runtime/proc.go:2945 +0x287 fp=0xc0000ddeb0 sp=0xc0000dde80 pc=0x403a457
runtime.cgocallbackg(0x0)
	/usr/local/go/src/runtime/cgocall.go:188 +0xa7 fp=0xc0000ddf18 sp=0xc0000ddeb0 pc=0x4009397
runtime.cgocallback_gofunc(0x404e66c, 0x405ef00, 0xc0000ddf98, 0x16)
	/usr/local/go/src/runtime/asm_amd64.s:773 +0x9b fp=0xc0000ddf38 sp=0xc0000ddf18 pc=0x405d03b
runtime.asmcgocall(0x405ef00, 0xc0000ddf98)
	/usr/local/go/src/runtime/asm_amd64.s:620 +0x42 fp=0xc0000ddf40 sp=0xc0000ddf38 pc=0x405ced2
runtime.libcCall(0x405ef00, 0xc0000ddf98, 0x2b)
	/usr/local/go/src/runtime/sys_darwin.go:46 +0x6c fp=0xc0000ddf70 sp=0xc0000ddf40 pc=0x404e66c
runtime.exit(0xc000000000)
	/usr/local/go/src/runtime/sys_darwin.go:199 +0x33 fp=0xc0000ddf98 sp=0xc0000ddf70 pc=0x404ebf3
runtime.main()
	/usr/local/go/src/runtime/proc.go:222 +0x261 fp=0xc0000ddfe0 sp=0xc0000ddf98 pc=0x4033221
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000ddfe8 sp=0xc0000ddfe0 pc=0x405d761

goroutine 34 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc190)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 35 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc3c0)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 36 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc730)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 37 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc960)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 38 [chan receive]:
main.handleEvents(0xc0000aa0c0, 0xc0000bc730, 0xc0000bc960)
	/Users/Philipp/go/src/github.com/muesli/telephant/events.go:56 +0x5b
created by main.setupMastodon
	/Users/Philipp/go/src/github.com/muesli/telephant/telephant.go:230 +0x308

goroutine 45 [select]:
net/http.(*http2ClientConn).roundTrip(0xc000130900, 0xc0001e0100, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/h2_bundle.go:7504 +0x8cc
net/http.(*http2Transport).RoundTripOpt(0xc000170000, 0xc0001e0100, 0xc00004b800, 0x42416e6, 0x0, 0xc000160120)
	/usr/local/go/src/net/http/h2_bundle.go:6867 +0x159
net/http.(*http2Transport).RoundTrip(...)
	/usr/local/go/src/net/http/h2_bundle.go:6829
net/http.http2noDialH2RoundTripper.RoundTrip(0xc000170000, 0xc0001e0100, 0xc000360740, 0x5, 0xc0001601a8)
	/usr/local/go/src/net/http/h2_bundle.go:8959 +0x3f
net/http.(*Transport).roundTrip(0x47b3880, 0xc0001e0100, 0x10, 0xc0000a72c0, 0xc00004bb80)
	/usr/local/go/src/net/http/transport.go:430 +0xe90
net/http.(*Transport).RoundTrip(0x47b3880, 0xc0001e0100, 0x47b3880, 0x0, 0x0)
	/usr/local/go/src/net/http/roundtrip.go:17 +0x35
net/http.send(0xc0001e0100, 0x44d2ce0, 0x47b3880, 0x0, 0x0, 0x0, 0xc000010288, 0xc000039e20, 0x1, 0x0)
	/usr/local/go/src/net/http/client.go:250 +0x461
net/http.(*Client).send(0xc0000c8680, 0xc0001e0100, 0x0, 0x0, 0x0, 0xc000010288, 0x0, 0x1, 0xe)
	/usr/local/go/src/net/http/client.go:174 +0xfb
net/http.(*Client).do(0xc0000c8680, 0xc0001e0100, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:641 +0x279
net/http.(*Client).Do(...)
	/usr/local/go/src/net/http/client.go:509
github.com/mattn/go-mastodon.(*Client).doStreaming(0xc0000c8680, 0xc0001e0100, 0xc0001740c0)
	/Users/Philipp/go/src/github.com/mattn/go-mastodon/streaming.go:114 +0x3c
github.com/mattn/go-mastodon.(*Client).streaming.func1(0xc0001740c0, 0x44deaa0, 0xc0000a8000, 0xc0000c8680, 0xc0001e0100)
	/Users/Philipp/go/src/github.com/mattn/go-mastodon/streaming.go:107 +0x6b
created by github.com/mattn/go-mastodon.(*Client).streaming
	/Users/Philipp/go/src/github.com/mattn/go-mastodon/streaming.go:98 +0x3dd

goroutine 10 [IO wait]:
internal/poll.runtime_pollWait(0x11100ea8, 0x72, 0xffffffffffffffff)
	/usr/local/go/src/runtime/netpoll.go:182 +0x56
internal/poll.(*pollDesc).wait(0xc000132118, 0x72, 0x2500, 0x2566, 0xffffffffffffffff)
	/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x9b
internal/poll.(*pollDesc).waitRead(...)
	/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000132100, 0xc0004b6000, 0x2566, 0x2566, 0x0, 0x0, 0x0)
	/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1f2
net.(*netFD).Read(0xc000132100, 0xc0004b6000, 0x2566, 0x2566, 0x203000, 0x0, 0x16d6)
	/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc0000a0008, 0xc0004b6000, 0x2566, 0x2566, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:177 +0x69
crypto/tls.(*atLeastReader).Read(0xc00047a3e0, 0xc0004b6000, 0x2566, 0x2566, 0x100, 0x6efffff, 0xc0001859e0)
	/usr/local/go/src/crypto/tls/conn.go:761 +0x60
bytes.(*Buffer).ReadFrom(0xc000107058, 0x44d2680, 0xc00047a3e0, 0x400f8e5, 0x43eb780, 0x4430640)
	/usr/local/go/src/bytes/buffer.go:207 +0xbd
crypto/tls.(*Conn).readFromUntil(0xc000106e00, 0x6f510e8, 0xc0000a0008, 0x5, 0xc0000a0008, 0x9)
	/usr/local/go/src/crypto/tls/conn.go:783 +0xf8
crypto/tls.(*Conn).readRecordOrCCS(0xc000106e00, 0x4467300, 0xc000106f38, 0xc000185d58)
	/usr/local/go/src/crypto/tls/conn.go:590 +0x125
crypto/tls.(*Conn).readRecord(...)
	/usr/local/go/src/crypto/tls/conn.go:558
crypto/tls.(*Conn).Read(0xc000106e00, 0xc0001b1000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/crypto/tls/conn.go:1236 +0x137
bufio.(*Reader).Read(0xc0001702a0, 0xc0001ca038, 0x9, 0x9, 0x400c5c4, 0xc0001629c0, 0xc000185d58)
	/usr/local/go/src/bufio/bufio.go:223 +0x23e
io.ReadAtLeast(0x44d2560, 0xc0001702a0, 0xc0001ca038, 0x9, 0x9, 0x9, 0x44d2780, 0xc0002fa9f0, 0xc000086050)
	/usr/local/go/src/io/io.go:310 +0x88
io.ReadFull(...)
	/usr/local/go/src/io/io.go:329
net/http.http2readFrameHeader(0xc0001ca038, 0x9, 0x9, 0x44d2560, 0xc0001702a0, 0x0, 0x0, 0xc0000ad5f0, 0x0)
	/usr/local/go/src/net/http/h2_bundle.go:1476 +0x88
net/http.(*http2Framer).ReadFrame(0xc0001ca000, 0xc0000ad5f0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/h2_bundle.go:1734 +0xa1
net/http.(*http2clientConnReadLoop).run(0xc000185fb8, 0x4466ce8, 0xc00003d7b8)
	/usr/local/go/src/net/http/h2_bundle.go:8102 +0x8f
net/http.(*http2ClientConn).readLoop(0xc000130900)
	/usr/local/go/src/net/http/h2_bundle.go:8030 +0x76
created by net/http.(*http2Transport).newClientConn
	/usr/local/go/src/net/http/h2_bundle.go:7093 +0x637

goroutine 44 [select]:
github.com/muesli/telephant/accounts/mastodon.(*Account).handleStream(0xc0000ad170)
	/Users/Philipp/go/src/github.com/muesli/telephant/accounts/mastodon/mastodon.go:517 +0x13f
created by github.com/muesli/telephant/accounts/mastodon.(*Account).Run
	/Users/Philipp/go/src/github.com/muesli/telephant/accounts/mastodon/mastodon.go:144 +0x511
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
panic during panic
SIGABRT: abort
PC=0x7fff6c0902c6 m=0 sigcode=0

goroutine 0 [idle]:
runtime.exit(0xc000000000)
	/usr/local/go/src/runtime/sys_darwin.go:199 +0x33 fp=0xc0000ddf98 sp=0xc0000ddf70 pc=0x404ebf3
runtime.main()
	/usr/local/go/src/runtime/proc.go:222 +0x261 fp=0xc0000ddfe0 sp=0xc0000ddf98 pc=0x4033221
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000ddfe8 sp=0xc0000ddfe0 pc=0x405d761

goroutine 1 [running, locked to thread]:
runtime.systemstack_switch()
	/usr/local/go/src/runtime/asm_amd64.s:311 fp=0xc0000dde18 sp=0xc0000dde10 pc=0x405b6b0
runtime.fatalthrow()
	/usr/local/go/src/runtime/panic.go:669 +0x57 fp=0xc0000dde50 sp=0xc0000dde18 pc=0x4031a47
runtime.throw(0x445d4dd, 0x2d)
	/usr/local/go/src/runtime/panic.go:617 +0x72 fp=0xc0000dde80 sp=0xc0000dde50 pc=0x4031872
runtime.exitsyscall()
	/usr/local/go/src/runtime/proc.go:2945 +0x287 fp=0xc0000ddeb0 sp=0xc0000dde80 pc=0x403a457
runtime.cgocallbackg(0x0)
	/usr/local/go/src/runtime/cgocall.go:188 +0xa7 fp=0xc0000ddf18 sp=0xc0000ddeb0 pc=0x4009397
runtime.cgocallback_gofunc(0x404e66c, 0x405ef00, 0xc0000ddf98, 0x16)
	/usr/local/go/src/runtime/asm_amd64.s:773 +0x9b fp=0xc0000ddf38 sp=0xc0000ddf18 pc=0x405d03b
runtime.asmcgocall(0x405ef00, 0xc0000ddf98)
	/usr/local/go/src/runtime/asm_amd64.s:620 +0x42 fp=0xc0000ddf40 sp=0xc0000ddf38 pc=0x405ced2
runtime.libcCall(0x405ef00, 0xc0000ddf98, 0x2b)
	/usr/local/go/src/runtime/sys_darwin.go:46 +0x6c fp=0xc0000ddf70 sp=0xc0000ddf40 pc=0x404e66c
runtime.exit(0xc000000000)
	/usr/local/go/src/runtime/sys_darwin.go:199 +0x33 fp=0xc0000ddf98 sp=0xc0000ddf70 pc=0x404ebf3
runtime.main()
	/usr/local/go/src/runtime/proc.go:222 +0x261 fp=0xc0000ddfe0 sp=0xc0000ddf98 pc=0x4033221
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc0000ddfe8 sp=0xc0000ddfe0 pc=0x405d761

goroutine 34 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc190)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 35 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc3c0)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 36 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc730)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 37 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc960)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 38 [chan receive]:
main.handleEvents(0xc0000aa0c0, 0xc0000bc730, 0xc0000bc960)
	/Users/Philipp/go/src/github.com/muesli/telephant/events.go:56 +0x5b
created by main.setupMastodon
	/Users/Philipp/go/src/github.com/muesli/telephant/telephant.go:230 +0x308

goroutine 45 [select]:
net/http.(*http2ClientConn).roundTrip(0xc000130900, 0xc0001e0100, 0x0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/h2_bundle.go:7504 +0x8cc
net/http.(*http2Transport).RoundTripOpt(0xc000170000, 0xc0001e0100, 0xc00004b800, 0x42416e6, 0x0, 0xc000160120)
	/usr/local/go/src/net/http/h2_bundle.go:6867 +0x159
net/http.(*http2Transport).RoundTrip(...)
	/usr/local/go/src/net/http/h2_bundle.go:6829
net/http.http2noDialH2RoundTripper.RoundTrip(0xc000170000, 0xc0001e0100, 0xc000360740, 0x5, 0xc0001601a8)
	/usr/local/go/src/net/http/h2_bundle.go:8959 +0x3f
net/http.(*Transport).roundTrip(0x47b3880, 0xc0001e0100, 0x10, 0xc0000a72c0, 0xc00004bb80)
	/usr/local/go/src/net/http/transport.go:430 +0xe90
net/http.(*Transport).RoundTrip(0x47b3880, 0xc0001e0100, 0x47b3880, 0x0, 0x0)
	/usr/local/go/src/net/http/roundtrip.go:17 +0x35
net/http.send(0xc0001e0100, 0x44d2ce0, 0x47b3880, 0x0, 0x0, 0x0, 0xc000010288, 0xc000039e20, 0x1, 0x0)
	/usr/local/go/src/net/http/client.go:250 +0x461
net/http.(*Client).send(0xc0000c8680, 0xc0001e0100, 0x0, 0x0, 0x0, 0xc000010288, 0x0, 0x1, 0xe)
	/usr/local/go/src/net/http/client.go:174 +0xfb
net/http.(*Client).do(0xc0000c8680, 0xc0001e0100, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/client.go:641 +0x279
net/http.(*Client).Do(...)
	/usr/local/go/src/net/http/client.go:509
github.com/mattn/go-mastodon.(*Client).doStreaming(0xc0000c8680, 0xc0001e0100, 0xc0001740c0)
	/Users/Philipp/go/src/github.com/mattn/go-mastodon/streaming.go:114 +0x3c
github.com/mattn/go-mastodon.(*Client).streaming.func1(0xc0001740c0, 0x44deaa0, 0xc0000a8000, 0xc0000c8680, 0xc0001e0100)
	/Users/Philipp/go/src/github.com/mattn/go-mastodon/streaming.go:107 +0x6b
created by github.com/mattn/go-mastodon.(*Client).streaming
	/Users/Philipp/go/src/github.com/mattn/go-mastodon/streaming.go:98 +0x3dd

goroutine 10 [IO wait]:
internal/poll.runtime_pollWait(0x11100ea8, 0x72, 0xffffffffffffffff)
	/usr/local/go/src/runtime/netpoll.go:182 +0x56
internal/poll.(*pollDesc).wait(0xc000132118, 0x72, 0x2500, 0x2566, 0xffffffffffffffff)
	/usr/local/go/src/internal/poll/fd_poll_runtime.go:87 +0x9b
internal/poll.(*pollDesc).waitRead(...)
	/usr/local/go/src/internal/poll/fd_poll_runtime.go:92
internal/poll.(*FD).Read(0xc000132100, 0xc0004b6000, 0x2566, 0x2566, 0x0, 0x0, 0x0)
	/usr/local/go/src/internal/poll/fd_unix.go:169 +0x1f2
net.(*netFD).Read(0xc000132100, 0xc0004b6000, 0x2566, 0x2566, 0x203000, 0x0, 0x16d6)
	/usr/local/go/src/net/fd_unix.go:202 +0x4f
net.(*conn).Read(0xc0000a0008, 0xc0004b6000, 0x2566, 0x2566, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/net.go:177 +0x69
crypto/tls.(*atLeastReader).Read(0xc00047a3e0, 0xc0004b6000, 0x2566, 0x2566, 0x100, 0x6efffff, 0xc0001859e0)
	/usr/local/go/src/crypto/tls/conn.go:761 +0x60
bytes.(*Buffer).ReadFrom(0xc000107058, 0x44d2680, 0xc00047a3e0, 0x400f8e5, 0x43eb780, 0x4430640)
	/usr/local/go/src/bytes/buffer.go:207 +0xbd
crypto/tls.(*Conn).readFromUntil(0xc000106e00, 0x6f510e8, 0xc0000a0008, 0x5, 0xc0000a0008, 0x9)
	/usr/local/go/src/crypto/tls/conn.go:783 +0xf8
crypto/tls.(*Conn).readRecordOrCCS(0xc000106e00, 0x4467300, 0xc000106f38, 0xc000185d58)
	/usr/local/go/src/crypto/tls/conn.go:590 +0x125
crypto/tls.(*Conn).readRecord(...)
	/usr/local/go/src/crypto/tls/conn.go:558
crypto/tls.(*Conn).Read(0xc000106e00, 0xc0001b1000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
	/usr/local/go/src/crypto/tls/conn.go:1236 +0x137
bufio.(*Reader).Read(0xc0001702a0, 0xc0001ca038, 0x9, 0x9, 0x400c5c4, 0xc0001629c0, 0xc000185d58)
	/usr/local/go/src/bufio/bufio.go:223 +0x23e
io.ReadAtLeast(0x44d2560, 0xc0001702a0, 0xc0001ca038, 0x9, 0x9, 0x9, 0x44d2780, 0xc0002fa9f0, 0xc000086050)
	/usr/local/go/src/io/io.go:310 +0x88
io.ReadFull(...)
	/usr/local/go/src/io/io.go:329
net/http.http2readFrameHeader(0xc0001ca038, 0x9, 0x9, 0x44d2560, 0xc0001702a0, 0x0, 0x0, 0xc0000ad5f0, 0x0)
	/usr/local/go/src/net/http/h2_bundle.go:1476 +0x88
net/http.(*http2Framer).ReadFrame(0xc0001ca000, 0xc0000ad5f0, 0x0, 0x0, 0x0)
	/usr/local/go/src/net/http/h2_bundle.go:1734 +0xa1
net/http.(*http2clientConnReadLoop).run(0xc000185fb8, 0x4466ce8, 0xc00003d7b8)
	/usr/local/go/src/net/http/h2_bundle.go:8102 +0x8f
net/http.(*http2ClientConn).readLoop(0xc000130900)
	/usr/local/go/src/net/http/h2_bundle.go:8030 +0x76
created by net/http.(*http2Transport).newClientConn
	/usr/local/go/src/net/http/h2_bundle.go:7093 +0x637

goroutine 44 [select]:
github.com/muesli/telephant/accounts/mastodon.(*Account).handleStream(0xc0000ad170)
	/Users/Philipp/go/src/github.com/muesli/telephant/accounts/mastodon/mastodon.go:517 +0x13f
created by github.com/muesli/telephant/accounts/mastodon.(*Account).Run
	/Users/Philipp/go/src/github.com/muesli/telephant/accounts/mastodon/mastodon.go:144 +0x511

rax    0x0
rbx    0xf6245c0
rcx    0x7ffeefbfecb8
rdx    0x0
rdi    0x307
rsi    0x6
rbp    0x7ffeefbfecf0
rsp    0x7ffeefbfecb8
r8     0x0
r9     0x7ffeefbfec10
r10    0x0
r11    0x206
r12    0x307
r13    0xfd88000
r14    0x6
r15    0x2d
rip    0x7fff6c0902c6
rflags 0x206
cs     0x7
fs     0x0
gs     0x0
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
stack trace unavailable
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
signal 6 received but handler not on signal stack
fatal error: non-Go code set up signal handler without SA_ONSTACK flag

runtime stack:
runtime: unexpected return pc for runtime.sigtramp called from 0xc0000022b8
stack: frame={sp:0xc000001e40, fp:0xc000001e50} stack=[0xbfffff9d80,0xc000002180)
000000c000001d40:  000000000445fe6d  0000000000000039
000000c000001d50:  000000c000001d70  000000000404654f <runtime.sigNotOnStack+127>
000000c000001d60:  000000000445fe6d  0000000000000039
000000c000001d70:  000000c000001e30  0000000004045bd3 <runtime.sigtrampgo+819>
000000c000001d80:  0000000000000006  000000c000001e00
000000c000001d90:  000000c000002320  0000000004021300 <runtime.gcMarkTermination+2768>
000000c000001da0:  0000000000000000  000000c000001e40
000000c000001db0:  0000000000000000  0000000000000000
000000c000001dc0:  0000000000000000  0000000000000000
000000c000001dd0:  0000000000000000  000000c000000000
000000c000001de0:  0000000000000000  0000000000000000
000000c000001df0:  0000000000000000  0000000000000000
000000c000001e00:  000000c000002000  0000000000008000
000000c000001e10:  0000000000000001  0000000000000000
000000c000001e20:  0000000000000000  0000000000000000
000000c000001e30:  000000c000001e80  000000000405f143 <runtime.sigtramp+51>
000000c000001e40: <0000000000000006 !000000c0000022b8
000000c000001e50: >000000c000002320  000000c000002320
000000c000001e60:  c2f4e5a4c6db400a  000000000fd95000
000000c000001e70:  0000000000000006  000000000000002d
000000c000001e80:  000000c000001e90  00007fff6c13ab5d
000000c000001e90:  000000c000002410  0000000000000000
000000c000001ea0:  0000000000000000  0000000000000000
000000c000001eb0:  0200014800000085  000000000fd96000
000000c000001ec0:  0000000000000000  000000000f6245c0
000000c000001ed0:  000000c0000023d8  0000000000000000
000000c000001ee0:  0000000000000307  0000000000000006
000000c000001ef0:  000000c000002410  000000c0000023d8
000000c000001f00:  0000000000000000  000000c000002330
000000c000001f10:  0000000000000000  0000000000000206
000000c000001f20:  0000000000000307  000000000fd95000
000000c000001f30:  0000000000000006  000000000000002d
000000c000001f40:  00007fff6c0902c6  0000000000000206
runtime.throw(0x445fe6d, 0x39)
	/usr/local/go/src/runtime/panic.go:617 +0x72
runtime.sigNotOnStack(0x6)
	/usr/local/go/src/runtime/signal_unix.go:576 +0x7f
runtime.sigtrampgo(0x6, 0xc0000022b8, 0xc000002320)
	/usr/local/go/src/runtime/signal_unix.go:334 +0x333
runtime: unexpected return pc for runtime.sigtramp called from 0xc0000022b8
stack: frame={sp:0xc000001e40, fp:0xc000001e50} stack=[0xbfffff9d80,0xc000002180)
000000c000001d40:  000000000445fe6d  0000000000000039
000000c000001d50:  000000c000001d70  000000000404654f <runtime.sigNotOnStack+127>
000000c000001d60:  000000000445fe6d  0000000000000039
000000c000001d70:  000000c000001e30  0000000004045bd3 <runtime.sigtrampgo+819>
000000c000001d80:  0000000000000006  000000c000001e00
000000c000001d90:  000000c000002320  0000000004021300 <runtime.gcMarkTermination+2768>
000000c000001da0:  0000000000000000  000000c000001e40
000000c000001db0:  0000000000000000  0000000000000000
000000c000001dc0:  0000000000000000  0000000000000000
000000c000001dd0:  0000000000000000  000000c000000000
000000c000001de0:  0000000000000000  0000000000000000
000000c000001df0:  0000000000000000  0000000000000000
000000c000001e00:  000000c000002000  0000000000008000
000000c000001e10:  0000000000000001  0000000000000000
000000c000001e20:  0000000000000000  0000000000000000
000000c000001e30:  000000c000001e80  000000000405f143 <runtime.sigtramp+51>
000000c000001e40: <0000000000000006 !000000c0000022b8
000000c000001e50: >000000c000002320  000000c000002320
000000c000001e60:  c2f4e5a4c6db400a  000000000fd95000
000000c000001e70:  0000000000000006  000000000000002d
000000c000001e80:  000000c000001e90  00007fff6c13ab5d
000000c000001e90:  000000c000002410  0000000000000000
000000c000001ea0:  0000000000000000  0000000000000000
000000c000001eb0:  0200014800000085  000000000fd96000
000000c000001ec0:  0000000000000000  000000000f6245c0
000000c000001ed0:  000000c0000023d8  0000000000000000
000000c000001ee0:  0000000000000307  0000000000000006
000000c000001ef0:  000000c000002410  000000c0000023d8
000000c000001f00:  0000000000000000  000000c000002330
000000c000001f10:  0000000000000000  0000000000000206
000000c000001f20:  0000000000000307  000000000fd95000
000000c000001f30:  0000000000000006  000000000000002d
000000c000001f40:  00007fff6c0902c6  0000000000000206
runtime.sigtramp(0xc000002320, 0xc000002320, 0xc2f4e5a4c6db400a, 0xfd95000, 0x6, 0x2d, 0xc000001e90, 0x7fff6c13ab5d, 0xc000002410, 0x0, ...)
	/usr/local/go/src/runtime/sys_darwin_amd64.s:206 +0x33
telephant(71489,0xf6245c0) malloc: *** error for object 0xa9437e0: pointer being freed was not allocated
telephant(71489,0xf6245c0) malloc: *** set a breakpoint in malloc_error_break to debug
panic during panic
SIGABRT: abort
PC=0x7fff6c0902c6 m=1 sigcode=0

goroutine 0 [idle]:
runtime.exit(0xc000000002)
	/usr/local/go/src/runtime/sys_darwin.go:199 +0x33
runtime.fatalthrow.func1()
	/usr/local/go/src/runtime/panic.go:679 +0x73
runtime.fatalthrow()
	/usr/local/go/src/runtime/panic.go:669 +0x57
runtime.throw(0x445fe6d, 0x39)
	/usr/local/go/src/runtime/panic.go:617 +0x72
runtime.sigNotOnStack(0x6)
	/usr/local/go/src/runtime/signal_unix.go:576 +0x7f
runtime.sigtrampgo(0x6, 0xc0000022b8, 0xc000002320)
	/usr/local/go/src/runtime/signal_unix.go:334 +0x333
runtime: unexpected return pc for runtime.sigtramp called from 0xc0000022b8
stack: frame={sp:0xc000001e40, fp:0xc000001e50} stack=[0xbfffff9d80,0xc000002180)
000000c000001d40:  000000000445fe6d  0000000000000039
000000c000001d50:  000000c000001d70  000000000404654f <runtime.sigNotOnStack+127>
000000c000001d60:  000000000445fe6d  0000000000000039
000000c000001d70:  000000c000001e30  0000000004045bd3 <runtime.sigtrampgo+819>
000000c000001d80:  0000000000000006  000000c000001e00
000000c000001d90:  000000c000002320  0000000004021300 <runtime.gcMarkTermination+2768>
000000c000001da0:  0000000000000000  000000c000001e40
000000c000001db0:  0000000000000000  0000000000000000
000000c000001dc0:  0000000000000000  0000000000000000
000000c000001dd0:  0000000000000000  000000c000000000
000000c000001de0:  0000000000000000  0000000000000000
000000c000001df0:  0000000000000000  0000000000000000
000000c000001e00:  000000c000002000  0000000000008000
000000c000001e10:  0000000000000001  0000000000000000
000000c000001e20:  0000000000000000  0000000000000000
000000c000001e30:  000000c000001e80  000000000405f143 <runtime.sigtramp+51>
000000c000001e40: <0000000000000006 !000000c0000022b8
000000c000001e50: >000000c000002320  000000c000002320
000000c000001e60:  c2f4e5a4c6db400a  000000000fd95000
000000c000001e70:  0000000000000006  000000000000002d
000000c000001e80:  000000c000001e90  00007fff6c13ab5d
000000c000001e90:  000000c000002410  0000000000000000
000000c000001ea0:  0000000000000000  0000000000000000
000000c000001eb0:  0200014800000085  000000000fd96000
000000c000001ec0:  0000000000000000  000000000f6245c0
000000c000001ed0:  000000c0000023d8  0000000000000000
000000c000001ee0:  0000000000000307  0000000000000006
000000c000001ef0:  000000c000002410  000000c0000023d8
000000c000001f00:  0000000000000000  000000c000002330
000000c000001f10:  0000000000000000  0000000000000206
000000c000001f20:  0000000000000307  000000000fd95000
000000c000001f30:  0000000000000006  000000000000002d
000000c000001f40:  00007fff6c0902c6  0000000000000206
runtime.sigtramp(0xc000002320, 0xc000002320, 0xc2f4e5a4c6db400a, 0xfd95000, 0x6, 0x2d, 0xc000001e90, 0x7fff6c13ab5d, 0xc000002410, 0x0, ...)
	/usr/local/go/src/runtime/sys_darwin_amd64.s:206 +0x33

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00004cfe8 sp=0xc00004cfe0 pc=0x405d761

goroutine 1 [running, locked to thread]:
	goroutine running on other thread; stack unavailable

goroutine 34 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc190)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 35 [sleep]:
runtime.goparkunlock(...)
	/usr/local/go/src/runtime/proc.go:307
time.Sleep(0xdf8475800)
	/usr/local/go/src/runtime/time.go:105 +0x159
main.(*MessageModel).init.func1(0xc0000bc3c0)
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:136 +0x30
created by main.(*MessageModel).init
	/Users/Philipp/go/src/github.com/muesli/telephant/messagemodel.go:134 +0xe64

goroutine 1 [??? (scan), locked to thread]:

Support for emojis

We should at least add a set of standard emojis. Some instances even support custom emojis.

multi-account support

Feature request:
Some method of switching between already authorized accounts without requesting a new auth token, or perhaps mixing feeds.

I don't know for sure if you planned this for later, but it's something I'd hope happens.

Media View Window

Currently, clicked pictures and media are opened in the browser, which might be many Spaces away. An in-app view window for pictures would be very nice.

The authorisation token link doesn't seem to be going to the correct URL?

In trying to get an authorisation code, I found that instead of bringing up the authorisation request page, it was simply opening a new tab and going straight /web/getting_started. I was able to get around this by instead copying the URL generated in the console output and pasting it into Firefox and that worked A-OK.

I'm guessing the URL used in the POST request might be getting malformed or something? I'm not sure, because around that point, there wasn't any other feedback.

Async loading of accounts and tweets

Content currently freezes the UI completely (Mac OS, 10.14.4) when it's loading from the server. Not sure if it's just my garbage internet connection, but having the main content window appear with even a loading indicator might make the UX slightly more fluid.

Doesn't display a window in Ubuntu

I'm not sure what the deal is, but I haven't been able to get Telephant to work since that first day when we did all that stuff figuring out the Ubuntu dependencies to get it working. There was a couple weeks in between that day and the next time I used it, so there's a decent time window in which things could've broken.

In regards to symptoms, the background process works fine, giving me system notifications for new mentions and stuff, but there's nothing in the foreground. No window or anything ever shows up. When launched outside the terminal, I have to kill it via the task manager. Luckily I can kill it with a simple CTRL-C in the terminal, though.

As for how it's broken, I'm not entirely sure. I don't know if the app simply doesn't update properly when I re-run the instructions or if the app actually broke.

I am getting an error message in the terminal, if it helps:

QQmlApplicationEngine failed to load component
qrc:/qml/telephant.qml:2 module "QtQuick.Controls" version 2.5 is not installed

Beyond that, I have nothing.

Conversation View

When clicking on replies, i want to see the conversation, not just in the browser, but in chirp itself.

Search Functionality is Limited

Search appears to be limited to usernames and toots that either you sent or someone sent to you.

Searching for tags (e.g. #floss, #supercollider, etc.) yield no results, even though clicking on a Tag in someone's comment brings up a bunch of toots for each one.

Similarly, if I were to look at a toot from in my home feed (one that I did not send out or one that I was addressed in) and then search for a word in that toot, that toot will not show up in the results. Again, the only toots that will come up are ones where I tooted using that word or someone addressed me and tooted that word.

I am requesting the Search Functionality be expanded accordingly.

Compiling on arm

I'm compiling telephant on arm with go version go1.8 linux/arm

when doing go get -u -v I get:


github.com/therecipe/qt/quickcontrols2
../../therecipe/qt/quickcontrols2/quickcontrols2.cpp:9:22: fatal error: QByteArray: No such file or directory
 #include <QByteArray>
                      ^
compilation terminated.
github.com/muesli/telephant/accounts/mastodon
# github.com/therecipe/qt/core
../../therecipe/qt/core/core.cpp:9:30: fatal error: QAbstractAnimation: No such file or directory
 #include <QAbstractAnimation>
                              ^
compilation terminated.

Hate Instance Blacklist

Given the recent discourse regarding Gab, I'm wondering about implementing a blacklist so that instances like Gab, Free Speech Extremist, etc. can't connect via your app. Their intolerance of marginalized groups should be met with equal intolerance, after all.

Add text in compose window explaining drag-and-drop media upload functionality

I was actually unaware of the ability to upload images via drag-and-drop functionality until I saw another issue report pertaining to it. Having a little bit of text below the line in the compose window explaining the feature like GitHub does in these compose windows would be extremely helpful because the feature isn't documented anywhere else, and the best way is to have it documented right there imo.

Document dependencies

I'm trying to build a Linux distribution package, and would appreciate more exact dependency information.

So far, in the binary packages, I've found:

  1. Without libpulse.so.0 (from PulseAudio or apulse) the application refuses to start.
  2. With a current OpenSSL (v1.1.0j), the application starts, but only text content is displayed, no icons or embedded images. Errors look like:
qt.network.ssl: QSslSocket: cannot resolve CRYPTO_num_locks
qt.network.ssl: QSslSocket: cannot resolve CRYPTO_set_id_callback
qt.network.ssl: QSslSocket: cannot resolve CRYPTO_set_locking_callback
qt.network.ssl: QSslSocket: cannot resolve ERR_free_strings
qt.network.ssl: QSslSocket: cannot resolve EVP_CIPHER_CTX_cleanup
qt.network.ssl: QSslSocket: cannot resolve EVP_CIPHER_CTX_init
qt.network.ssl: QSslSocket: cannot resolve sk_new_null
qt.network.ssl: QSslSocket: cannot resolve sk_push
qt.network.ssl: QSslSocket: cannot resolve sk_free
qt.network.ssl: QSslSocket: cannot resolve sk_num
qt.network.ssl: QSslSocket: cannot resolve sk_pop_free
qt.network.ssl: QSslSocket: cannot resolve sk_value
qt.network.ssl: QSslSocket: cannot resolve SSL_library_init
qt.network.ssl: QSslSocket: cannot resolve SSL_load_error_strings
qt.network.ssl: QSslSocket: cannot resolve SSL_get_ex_new_index
qt.network.ssl: QSslSocket: cannot resolve SSLv3_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv23_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv3_server_method
qt.network.ssl: QSslSocket: cannot resolve SSLv23_server_method
qt.network.ssl: QSslSocket: cannot resolve X509_STORE_CTX_get_chain
qt.network.ssl: QSslSocket: cannot resolve OPENSSL_add_all_algorithms_noconf
qt.network.ssl: QSslSocket: cannot resolve OPENSSL_add_all_algorithms_conf
qt.network.ssl: QSslSocket: cannot resolve SSLeay
qt.network.ssl: Incompatible version of OpenSSL
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

When installing an old v1.0.2r OpenSSL, it works as intended. OpenSSL had a substantial API break between v1.0 and v1.1.

Delete and Redraft option

Just a nice quality-of-life feature - being able to delete a toot and preserve the content for editing :)

Use Flutter

I used to use golang with QT but changed to using Flutter with golang.
Why ?
All Desktops and Mobiles from the SAME codebase.
Much easier going forward because there are so many plugins for Flutter.
There is really NOTHING to change between Mobile and Desktop.
If the Mobile uses a plugin that relies on a swift or java lib, you can easily support the plugin for Desktop too because the API is identical, and because for Desktop you write the plugin in golang its normally easy to support.
For a Great example of this look at PDF and Printing, which is really hard normally.
Fluttter Widgets can output to PDF (https://github.com/DavBfr/dart_pdf) . SO you can print on Mobile and Desktop.
But the Printer API varies. But you can easily support this on Desktop by just writing a bit of CGO code for desktops and your done.

I would really be interested in adapting the current code for Flutter if the team want it.

The Flutter Desktop system:
https://github.com/go-flutter-desktop/go-flutter

The only change is to add a main_desktop.dart.

Impossible to open posts with images but no text

Any posts containing images, but without any text are impossible to expand into conversation view.

Mastodon's webapp has this issue too, but they have a dropdown menu with an "Expand this status" option to get around it. Meanwhile, in mobile apps such as Tusky, tapping in the empty margins (i.e. below the avatar & to the left of the picture or on the right side of the picture) opens it up, so that could be a solution here too. I find this route much more intuitive than adding a dropdown menu item anyway.

Readme issues

The windows static build link leads to a 404 page, the linux static build doesn't seem to have a filetype in the name when downloaded, and the dependency commands are missing the sudo command

Add file chooser for media upload

This is a complement issue report to #47, but since it's technically a different feature, I'm giving it its own issue report.

Some people prefer the drag-and-drop method, but others, such as myself, are more used to clicking a button and selecting a file that way. I believe you're planning on mobile builds too, judging by the readme saying mobile builds are untested atm, so if they're to ever have media upload functions, this will be required since Android doesn't do drag-and-drop.

Build error with makechrootpkg

Trying to rebuild telephant-git hasn't worked out, I got some qt go bindings related error:

# github.com/therecipe/qt/core
core-minimal.cpp: In function ‘long long int QLineF_Intersect(void*, void*, void*)’:
core-minimal.cpp:3094:115: warning: ‘QLineF::IntersectType QLineF::intersect(const QLineF&, QPointF*) const’ is deprecated: Use intersects() instead [-Wdeprecated-declarations]
 3094 |  return static_cast<QLineF*>(ptr)->intersect(*static_cast<QLineF*>(line), static_cast<QPointF*>(intersectionPoint));
      |                                                                                                                   ^
In file included from /usr/include/qt/QtCore/QLine:1,
                 from core-minimal.cpp:36:
/usr/include/qt/QtCore/qline.h:256:19: note: declared here
  256 |     IntersectType intersect(const QLineF &l, QPointF *intersectionPoint) const;
      |                   ^~~~~~~~~
core-minimal.cpp: In function ‘int QTime_Restart(void*)’:
core-minimal.cpp:4901:43: warning: ‘int QTime::restart()’ is deprecated: Use QElapsedTimer instead [-Wdeprecated-declarations]
 4901 |  return static_cast<QTime*>(ptr)->restart();
      |                                           ^
In file included from /usr/include/qt/QtCore/qcborvalue.h:44,
                 from /usr/include/qt/QtCore/QCborValue:1,
                 from core-minimal.cpp:19:
/usr/include/qt/QtCore/qdatetime.h:229:54: note: declared here
  229 |     QT_DEPRECATED_X("Use QElapsedTimer instead") int restart();
      |                                                      ^~~~~~~
core-minimal.cpp: In function ‘void QTime_Start(void*)’:
core-minimal.cpp:4911:34: warning: ‘void QTime::start()’ is deprecated: Use QElapsedTimer instead [-Wdeprecated-declarations]
 4911 |  static_cast<QTime*>(ptr)->start();
      |                                  ^
In file included from /usr/include/qt/QtCore/qcborvalue.h:44,
                 from /usr/include/qt/QtCore/QCborValue:1,
                 from core-minimal.cpp:19:
/usr/include/qt/QtCore/qdatetime.h:228:55: note: declared here
  228 |     QT_DEPRECATED_X("Use QElapsedTimer instead") void start();
      |                                                       ^~~~~
github.com/therecipe/qt/qml
github.com/therecipe/qt/internal/binding/runtime
# github.com/therecipe/qt/internal/binding/runtime
moc.cpp: In function ‘int helper7390ef_helper7390ef_QmlRegisterType()’:
moc.cpp:76:39: warning: ‘int qmlRegisterType() [with T = helper7390ef]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
   76 |  return qmlRegisterType<helper7390ef>();
      |                                       ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:24:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:76:39: warning: ‘int qmlRegisterType() [with T = helper7390ef]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
   76 |  return qmlRegisterType<helper7390ef>();
      |                                       ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:24:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
github.com/therecipe/qt/gui
github.com/therecipe/qt/quickcontrols2
github.com/muesli/telephant
# github.com/muesli/telephant
moc.cpp: In function ‘int ConfigBridge722e73_ConfigBridge722e73_QmlRegisterType()’:
moc.cpp:1156:45: warning: ‘int qmlRegisterType() [with T = ConfigBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 1156 |  return qmlRegisterType<ConfigBridge722e73>();
      |                                             ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:1156:45: warning: ‘int qmlRegisterType() [with T = ConfigBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 1156 |  return qmlRegisterType<ConfigBridge722e73>();
      |                                             ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int AccountBridge722e73_AccountBridge722e73_QmlRegisterType()’:
moc.cpp:1841:46: warning: ‘int qmlRegisterType() [with T = AccountBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 1841 |  return qmlRegisterType<AccountBridge722e73>();
      |                                              ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:1841:46: warning: ‘int qmlRegisterType() [with T = AccountBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 1841 |  return qmlRegisterType<AccountBridge722e73>();
      |                                              ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int Attachment722e73_Attachment722e73_QmlRegisterType()’:
moc.cpp:2001:43: warning: ‘int qmlRegisterType() [with T = Attachment722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 2001 |  return qmlRegisterType<Attachment722e73>();
      |                                           ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:2001:43: warning: ‘int qmlRegisterType() [with T = Attachment722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 2001 |  return qmlRegisterType<Attachment722e73>();
      |                                           ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int MessageModel722e73_MessageModel722e73_QmlRegisterType()’:
moc.cpp:2256:45: warning: ‘int qmlRegisterType() [with T = MessageModel722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 2256 |  return qmlRegisterType<MessageModel722e73>();
      |                                             ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:2256:45: warning: ‘int qmlRegisterType() [with T = MessageModel722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 2256 |  return qmlRegisterType<MessageModel722e73>();
      |                                             ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int Pane722e73_Pane722e73_QmlRegisterType()’:
moc.cpp:3026:37: warning: ‘int qmlRegisterType() [with T = Pane722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 3026 |  return qmlRegisterType<Pane722e73>();
      |                                     ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:3026:37: warning: ‘int qmlRegisterType() [with T = Pane722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 3026 |  return qmlRegisterType<Pane722e73>();
      |                                     ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int PaneModel722e73_PaneModel722e73_QmlRegisterType()’:
moc.cpp:3271:42: warning: ‘int qmlRegisterType() [with T = PaneModel722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 3271 |  return qmlRegisterType<PaneModel722e73>();
      |                                          ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:3271:42: warning: ‘int qmlRegisterType() [with T = PaneModel722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 3271 |  return qmlRegisterType<PaneModel722e73>();
      |                                          ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int ProfileBridge722e73_ProfileBridge722e73_QmlRegisterType()’:
moc.cpp:4391:46: warning: ‘int qmlRegisterType() [with T = ProfileBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 4391 |  return qmlRegisterType<ProfileBridge722e73>();
      |                                              ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:4391:46: warning: ‘int qmlRegisterType() [with T = ProfileBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 4391 |  return qmlRegisterType<ProfileBridge722e73>();
      |                                              ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int UIBridge722e73_UIBridge722e73_QmlRegisterType()’:
moc.cpp:4647:41: warning: ‘int qmlRegisterType() [with T = UIBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 4647 |  return qmlRegisterType<UIBridge722e73>();
      |                                         ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:4647:41: warning: ‘int qmlRegisterType() [with T = UIBridge722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 4647 |  return qmlRegisterType<UIBridge722e73>();
      |                                         ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int AttachmentModel722e73_AttachmentModel722e73_QmlRegisterType()’:
moc.cpp:4892:48: warning: ‘int qmlRegisterType() [with T = AttachmentModel722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 4892 |  return qmlRegisterType<AttachmentModel722e73>();
      |                                                ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:4892:48: warning: ‘int qmlRegisterType() [with T = AttachmentModel722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 4892 |  return qmlRegisterType<AttachmentModel722e73>();
      |                                                ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp: In function ‘int Message722e73_Message722e73_QmlRegisterType()’:
moc.cpp:5662:40: warning: ‘int qmlRegisterType() [with T = Message722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 5662 |  return qmlRegisterType<Message722e73>();
      |                                        ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
moc.cpp:5662:40: warning: ‘int qmlRegisterType() [with T = Message722e73]’ is deprecated: Use qmlRegisterAnonymousType instead [-Wdeprecated-declarations]
 5662 |  return qmlRegisterType<Message722e73>();
      |                                        ^
In file included from /usr/include/qt/QtQml/qqmlengine.h:47,
                 from /usr/include/qt/QtQml/QQmlEngine:1,
                 from moc.cpp:33:
/usr/include/qt/QtQml/qqml.h:138:74: note: declared here
  138 | QT_DEPRECATED_VERSION_X_5_14("Use qmlRegisterAnonymousType instead") int qmlRegisterType()
      |                                                                          ^~~~~~~~~~~~~~~
# github.com/muesli/telephant
./telephant.go:142:23: too many arguments in call to gap.NewScope
        have (gap.ScopeType, string, string)
        want (gap.ScopeType, string)

==> ERROR: A failure occurred in build().
    Aborting...

Telephant Trying to Read Posts Even When No Account Authorized

When I first started Telephant, it immediately showed some errors in the terminal output. I hadn't had a chance to even begin typing my instance name for the authorization process, meaning Telephant doesn't distinguish whether or not it actually has authorization or even a site to go to before it tries to fetch posts.

The errors were about a dozen of the following:
qrc:/qml/MessageView.qml:246: TypeError: Cannot read property 'x' of undefined
where 'x' is a bunch of various properties such as 'author', 'body', 'mediapreview', etc.

replying to a thread you last tooted in only mentions/dms yourself

Behavior:
Clicking on a toot in a thread that you were the last toot in only mentions yourself.

Expected behavior:
Should also grab those mentioned in toot you're replying too.

Muesli:
Mentioned this already from my niu.moe account, but thought'd be better to have an issue here for tracking purposes. Also, maybe this is intended; it just isn't how the web interface or any other client's I've used behave. If so feel free to close issue

Hearts don't turn red

They should turn red when liking a tweet. Also, the retweet button should turn all colourfull when retweeting something!

Text Box Boundaries

When rezising the window too narrow horizontally, text boxes start exceeding their boundaries like seen here

Hotkey for new tweet

A hotkey for new tweets or various other functions would be great. Even configurable, best case :)

Support for additional panes

I'd love the ability to add additional panes, eg. for the local timeline, federated timeline, "DMs", or searches.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.