Browse Source

Resolve static asset embedding issue

wip
Trevor Slocum 2 years ago
parent
commit
3e2bdbd964
  1. 1
      .gitignore
  2. 3
      CHANGELOG
  3. 4
      goreleaser.yml
  4. 4
      pkg/web/assets.go
  5. 7
      pkg/web/assets_embed.go
  6. 14
      pkg/web/channel.go
  7. 65
      pkg/web/public/assets/css/harmony.css
  8. 29
      pkg/web/public/assets/js/harmony.js
  9. 48
      pkg/web/public/index.html
  10. 32
      pkg/web/web.go

1
.gitignore

@ -6,4 +6,5 @@ harmony
!pkg/harmony/
harmony-server
!cmd/harmony-server/
pkg/web/assets_embed.go
vendor/

3
CHANGELOG

@ -1,2 +1,5 @@
0.1.1:
- Fix static asset embedding issue
0.1.0:
- Initial release

4
goreleaser.yml

@ -3,6 +3,10 @@ project_name: harmony
env:
- GO111MODULE=on
- CGO_ENABLED=1
before:
hooks:
- go get github.com/omeid/go-resources/cmd/resources
- resources -output=./pkg/web/assets_embed.go -tag=embed -package=web -var=assets -trim=pkg/web/public/ pkg/web/public/* pkg/web/public/assets/* pkg/web/public/assets/css/* pkg/web/public/assets/js/*
builds:
-
id: harmony-server

4
pkg/web/assets.go

@ -4,4 +4,6 @@ package web
import "github.com/omeid/go-resources/live"
var assets = live.Dir("./public")
func init() {
assets = live.Dir("./public")
}

7
pkg/web/assets_embed.go

@ -1,7 +0,0 @@
// +build embed
package web
import "net/http"
var assets http.FileSystem

14
pkg/web/channel.go

@ -0,0 +1,14 @@
package web
type Channel struct {
ID int
Name string
Topic string
Clients map[int]*Client
}
func NewChannel(id int, name string, topic string) *Channel {
c := Channel{ID: id, Name: name, Topic: topic, Clients: make(map[int]*Client)}
return &c
}

65
pkg/web/public/assets/css/harmony.css

@ -1,5 +1,6 @@
* {
box-sizing: border-box;
font-family: Helvetica, arial, sans-serif;
}
html, body {
@ -24,6 +25,8 @@ nav ul, aside ul {
overflow-x: auto;
overflow-y: scroll;
border-bottom: 1px solid #cecece;
}
.sideright {
@ -31,10 +34,16 @@ nav ul, aside ul {
overflow-x: auto;
overflow-y: scroll;
border-bottom: 1px solid #cecece;
}
.status {
grid-area: status;
overflow-x: auto;
overflow-y: scroll;
border-bottom: 1px solid #cecece;
}
.footer {
@ -44,20 +53,23 @@ nav ul, aside ul {
.wrapper {
margin: 0;
width: 100vw;
height: 100vh;
min-height: 100vh;
display: grid;
grid-gap: 0;
grid-template-areas: "sideleft" "sideright" "content" "status" "footer";
grid-template-columns: 1fr;
grid-template-rows: min-content min-content min-content 1fr min-content min-content;
grid-template-areas: "sideleft" "sideright" "header" "content" "status" "footer";
font: 1.2em Helvetica, arial, sans-serif;
font-size: 1.2em;
}
@media (min-width: 500px) {
.wrapper {
height: 100vh;
grid-template-columns: 1fr 4fr;
grid-template-rows: 1fr 1fr min-content min-content;
grid-template-areas: "sideleft content" "sideright content" "status content" "footer footer";
grid-template-rows: min-content 1fr 1fr min-content min-content;
grid-template-areas: "sideleft header" "sideleft content" "sideright content" "status content" "footer footer";
}
#voiceptt {
@ -71,9 +83,10 @@ nav ul, aside ul {
@media (min-width: 750px) {
.wrapper {
height: 100vh;
grid-template-columns: 1fr 5fr 1fr;
grid-template-rows: 1fr min-content min-content;
grid-template-areas: "sideleft content sideright" "status content sideright" "footer footer footer"
grid-template-rows: min-content 1fr min-content min-content;
grid-template-areas: "sideleft header sideright" "sideleft content sideright" "status content sideright" "footer footer footer"
}
#voiceptt {
@ -85,10 +98,17 @@ nav ul, aside ul {
}
}
.sideleft, .sideright, .status, .content, .footer {
.sideleft, .sideright, .status, .content {
padding: 7px;
}
.header {
padding: 10px;
overflow-x: auto;
overflow-y: scroll;
}
.content {
padding-left: 10px;
padding-right: 10px;
@ -99,10 +119,22 @@ button {
padding: 7px;
}
button, #chathistory, #chatinput {
#mainheader {
font-size: 1.5em;
}
button, #subheader, #chathistory, #chatinput, .status {
font-size: 1.25em;
}
#header, #status {
vertical-align: center;
}
.header {
border-right: 1px solid #cecece;
}
.headericon {
display: inline-block;
width: 25px;
@ -116,21 +148,26 @@ button, #chathistory, #chatinput {
overflow-x: auto;
overflow-y: scroll;
font-family: monospace;
min-height: 150px;
border: 1px solid #cecece;
}
#chatinput {
width: 100%;
display:block;
height: 100%;
border: 0;
resize: none;
}
#voicepttcontainer {
border-top: 1px solid #cecece;
}
#voiceptt {
width: 100%;
height: 125px;
margin-top: 7px;
margin-bottom: 14px;
border: 0;
}
.voiceinactive {
@ -142,4 +179,4 @@ button, #chathistory, #chatinput {
display: inline-block;
width: 27px;
padding-left: 4px;
}
}

29
pkg/web/public/assets/js/harmony.js

@ -14,9 +14,13 @@ var numConnections = 3;
var peerConnections = [];
var RTCConstraints = {
audio: {
channelCount: {exact: 2},
autoGainControl: false,
echoCancellation: false,
noiseSuppression: false,
sampleRate: 48000,
sampleSize: 16,
volume: 1.0
},
video: false
};
@ -51,10 +55,10 @@ var MessageTopic = 114;
var MessageAction = 115;
var MessageDisconnect = 119;
var MessageChat = 120;
var MessageTypingStart = 121;
var MessageTypingStop = 122;
var MessageTypingStart = 121;
var MessageTypingStop = 122;
var MessageTransmitStart = 123;
var MessageTransmitStop = 124;
var MessageTransmitStop = 124;
var MessageUsers = 130;
var tagsToReplace = {
@ -95,6 +99,8 @@ function HandleInput(e) {
$(document).ready(function () {
$("#togglevoice").on("click touchstart", function () {
$("#chatinput").focus();
if (peerConnections.length > 0 || voice) {
// Quit voice chat
@ -107,7 +113,6 @@ $(document).ready(function () {
});
peerConnections = [];
$('#voicepttheader').css('display', 'none');
$('#voicepttcontainer').css('display', 'none');
updateStatus();
@ -127,6 +132,8 @@ $(document).ready(function () {
StartPTT();
$("#chatinput").focus();
return false;
});
@ -135,6 +142,8 @@ $(document).ready(function () {
StartPTT();
$("#chatinput").focus();
return false;
});
@ -154,7 +163,7 @@ $(document).ready(function () {
return false;
});
$("#inputheader, #voicepttheader").on("click touchstart", function (e) {
$("#chatinputcontainer,#voicepttcontainer").on("click touchstart", function (e) {
$("#chatinput").focus();
return false;
@ -213,8 +222,7 @@ function createPeerConnection(id) {
Log("Note: Push-to-talk is bound to <F8>");
}
$('#voicepttheader').css('display', 'table-row');
$('#voicepttcontainer').css('display', 'table-row');
$('#voicepttcontainer').css('display', 'block');
updateStatus();
};
@ -275,6 +283,7 @@ function Connect() {
return;
}
userPing = 0;
userListStatus = 'Connecting...';
updateStatus();
@ -359,7 +368,7 @@ function Connect() {
}
Log(escapeEntities(p.N) + " disconnected");
} else if (p.T == MessageNick) {
} else if (p.T == MessageNick) {
if (p.N === undefined) {
return;
}
@ -459,6 +468,10 @@ function waitForSocketConnection(socket, callback) {
}
function Log(msg) {
if (msg.charAt(0) != '<' && msg.charAt(0) != '&' && msg.charAt(1) != '&' && msg.charAt(2) != 't' && msg.charAt(3) != ';') {
msg = '* ' + msg;
}
var date = new Date();
$('#chathistory').append(chatprefix + date.getHours() + ":" + (date.getMinutes() < 10 ? "0" : "") + date.getMinutes() + " " + msg + "\n")
$('#chathistory').scrollTop($('#chathistory').prop("scrollHeight"));

48
pkg/web/public/index.html

@ -11,12 +11,18 @@
<div class="wrapper">
<nav class="sideleft" id="sideleft">
<ul>
<li style="margin-bottom: 10px;"><div class="headericon">&#128240;</div>Text Channels</li>
<ul class="widelinks" style="padding-left: 5px;">
<li><b>#lobby</b></li>
</ul>
<li style="margin-bottom: 10px;">
<div class="headericon">&#128240;</div>
Text Channels
</li>
<ul class="widelinks" style="padding-left: 5px;">
<li><b>#lobby</b></li>
</ul>
<li style="margin-bottom: 10px;">&nbsp;</li>
<li style="margin-bottom: 10px;"><div class="headericon">&#128266;</div> Voice Channels</li>
<li style="margin-bottom: 10px;">
<div class="headericon">&#128266;</div>
Voice Channels
</li>
<ul style="padding-left: 5px;">
<li style="margin-bottom: 5px;"><b>&lobby</b> &nbsp; <a href="#" id="togglevoice">Join</a></li>
<li id="userlistvoice1"></li>
@ -27,32 +33,20 @@
</article>
<aside class="sideright" id="sideright">
</aside>
<div class="header" id="header">
<div style="display: inline-block;float: left;" id="mainheader">#lobby</div>
<div style="display: inline-block;float: right;" id="subheader">harmony demo</div>
</div>
<div class="status">
<div id="userstatus">Loading...</div>
</div>
<footer class="footer">
<table width="100%">
<tr id="inputheader">
<td colspan="2">
<hr style="color: #eeeeee;">
</td>
</tr>
<tr>
<td id="inputcontainer" colspan="2">
<textarea id="chatinput" placeholder="Message #lobby" rows="2"></textarea>
</td>
</tr>
<tr id="voicepttheader" style="display: none;">
<td colspan="2">
<hr style="color: #eeeeee;">
</td>
</tr>
<tr id="voicepttcontainer" style="display: none;">
<td colspan="2">
<button id="voiceptt">Push-To-Talk</button>
</td>
</tr>
</table>
<div style="padding: 7px;" id="chatinputcontainer">
<textarea id="chatinput" placeholder="Message #lobby" rows="2"></textarea>
</div>
<div id="voicepttcontainer" style="display: none;">
<button id="voiceptt">Push-To-Talk</button>
</div>
</footer>
</div>
<div style="display: none" id="hidden">

32
pkg/web/web.go

@ -30,6 +30,8 @@ var peerConnectionConfig = webrtc.Configuration{
},
}
var assets http.FileSystem
var incomingClients = make(chan *Client, 10)
var markdownRenderer = markdown.New(markdown.Typographer(false), markdown.Breaks(true), markdown.Quotes([]string{`"`, `"`, `'`, `'`}))
@ -54,14 +56,19 @@ type Message struct {
type WebInterface struct {
Clients map[int]*Client
ClientsLock *sync.Mutex
Channels map[int]*Channel
ChannelsLock *sync.Mutex
}
func NewWebInterface(address string, path string) *WebInterface {
if assets == nil {
panic("web assets not found")
panic("failed to load web assets")
}
w := WebInterface{Clients: make(map[int]*Client), ClientsLock: new(sync.Mutex)}
w := WebInterface{Clients: make(map[int]*Client), ClientsLock: new(sync.Mutex), Channels: make(map[int]*Channel), ChannelsLock: new(sync.Mutex)}
w.createChannels()
r := mux.NewRouter()
@ -87,6 +94,25 @@ func NewWebInterface(address string, path string) *WebInterface {
return &w
}
func (w *WebInterface) createChannels() {
w.ChannelsLock.Lock()
defer w.ChannelsLock.Unlock()
ch := NewChannel(w.nextChannelID(), "lobby", "harmony demo server")
w.Channels[ch.ID] = ch
}
func (w *WebInterface) nextChannelID() int {
id := 0
for cid := range w.Channels {
if cid > id {
id = cid
}
}
return id + 1
}
func (w *WebInterface) handleIncomingClients() {
for c := range incomingClients {
c := c // Capture
@ -178,7 +204,7 @@ func (w *WebInterface) handleRead(c *Client) {
msg.M = msg.M[3 : len(msg.M)-4]
}
msg.M = bytes.ReplaceAll(msg.M, []byte(`<a href="`), []byte(`<a target="_blank" href="`))
msg.M = bytes.TrimSpace(bytes.ReplaceAll(msg.M, []byte(`<a href="`), []byte(`<a target="_blank" href="`)))
w.ClientsLock.Lock()

Loading…
Cancel
Save