Resolve static asset embedding issue
This commit is contained in:
parent
c2def0b254
commit
3e2bdbd964
|
@ -6,4 +6,5 @@ harmony
|
|||
!pkg/harmony/
|
||||
harmony-server
|
||||
!cmd/harmony-server/
|
||||
pkg/web/assets_embed.go
|
||||
vendor/
|
||||
|
|
|
@ -1,2 +1,5 @@
|
|||
0.1.1:
|
||||
- Fix static asset embedding issue
|
||||
|
||||
0.1.0:
|
||||
- Initial release
|
||||
|
|
|
@ -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,4 +4,6 @@ package web
|
|||
|
||||
import "github.com/omeid/go-resources/live"
|
||||
|
||||
var assets = live.Dir("./public")
|
||||
func init() {
|
||||
assets = live.Dir("./public")
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
// +build embed
|
||||
|
||||
package web
|
||||
|
||||
import "net/http"
|
||||
|
||||
var assets http.FileSystem
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -11,12 +11,18 @@
|
|||
<div class="wrapper">
|
||||
<nav class="sideleft" id="sideleft">
|
||||
<ul>
|
||||
<li style="margin-bottom: 10px;"><div class="headericon">📰</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">📰</div>
|
||||
Text Channels
|
||||
</li>
|
||||
<ul class="widelinks" style="padding-left: 5px;">
|
||||
<li><b>#lobby</b></li>
|
||||
</ul>
|
||||
<li style="margin-bottom: 10px;"> </li>
|
||||
<li style="margin-bottom: 10px;"><div class="headericon">🔊</div> Voice Channels</li>
|
||||
<li style="margin-bottom: 10px;">
|
||||
<div class="headericon">🔊</div>
|
||||
Voice Channels
|
||||
</li>
|
||||
<ul style="padding-left: 5px;">
|
||||
<li style="margin-bottom: 5px;"><b>&lobby</b> <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">
|
||||
|
|
|
@ -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…
Reference in New Issue