* VRFS-2608 - refactor and slight cleanup of UI towards new spec
This commit is contained in:
parent
1cb9f47f6c
commit
af83a4f6a1
|
|
@ -8,6 +8,9 @@ module JamRuby
|
|||
|
||||
# Interact with external python tools to create the JKZ
|
||||
class JamTracksManager
|
||||
|
||||
@@log = Logging.logger[JamTracksManager]
|
||||
|
||||
class << self
|
||||
def save_jam_track_jkz(user, jam_track)
|
||||
jam_track_right = jam_track.right_for_user(user)
|
||||
|
|
@ -36,7 +39,7 @@ module JamRuby
|
|||
title=jam_track.name
|
||||
output_jkz=File.join(tmp_dir, "#{title.parameterize}.jkz")
|
||||
py_file = File.join(py_root, "jkcreate.py")
|
||||
puts "Executing python source in #{py_file}, outputting to #{tmp_dir} (#{output_jkz})"
|
||||
@@log.info "Executing python source in #{py_file}, outputting to #{tmp_dir} (#{output_jkz})"
|
||||
|
||||
# From http://stackoverflow.com/questions/690151/getting-output-of-system-calls-in-ruby/5970819#5970819:
|
||||
cli = "python #{py_file} -D -k #{sku} -p #{tmp_dir}/pkey.pem -s #{tmp_dir}/skey.pem #{jam_file_opts} -o #{output_jkz} -t '#{title}'"
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@
|
|||
|
||||
var $fader = $(this);
|
||||
|
||||
var recordingDisabled = $fader.data('recording-disabled');
|
||||
if(recordingDisabled) {
|
||||
var recordingOpener = $fader.data('recording-opener');
|
||||
window.JK.prodBubble($fader, 'recording-controls-disabled', {recordingOpener:recordingOpener}, {positions:['top'], offsetParent: $fader.closest('.screen')})
|
||||
var mediaControlsDisabled = $fader.data('media-controls-disabled');
|
||||
if(mediaControlsDisabled) {
|
||||
var mediaTrackOpener = $fader.data('media-track-opener');
|
||||
window.JK.prodBubble($fader, 'media-controls-disabled', {mediaTrackOpener:mediaTrackOpener}, {positions:['top'], offsetParent: $fader.closest('.screen')})
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -127,10 +127,10 @@
|
|||
$draggingFader = $draggingFaderHandle.closest('div[control="fader"]');
|
||||
draggingOrientation = $draggingFader.attr('orientation');
|
||||
|
||||
var recordingDisabled = $draggingFaderHandle.data('recording-disabled');
|
||||
var recordingOpener = $draggingFaderHandle.data('recording-opener');
|
||||
var mediaControlsDisabled = $draggingFaderHandle.data('media-controls-disabled');
|
||||
var mediaTrackOpener = $draggingFaderHandle.data('media-track-opener');
|
||||
|
||||
if(recordingDisabled) {
|
||||
if(mediaControlsDisabled) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -179,7 +179,7 @@
|
|||
|
||||
selector.html(g._.template(templateSource, options));
|
||||
|
||||
selector.find('div[control="fader"]').data('recording-disabled', selector.data('recording-disabled')).data('recording-opener', selector.data('recording-opener'))
|
||||
selector.find('div[control="fader"]').data('media-controls-disabled', selector.data('media-controls-disabled')).data('media-track-opener', selector.data('media-track-opener'))
|
||||
|
||||
selector.find('div[control="fader-handle"]').draggable({
|
||||
drag: onFaderDrag,
|
||||
|
|
@ -187,7 +187,7 @@
|
|||
stop: onFaderDragStop,
|
||||
containment: "parent",
|
||||
axis: options.faderType === 'horizontal' ? 'x' : 'y'
|
||||
}).data('recording-disabled', selector.data('recording-disabled')).data('recording-opener', selector.data('recording-opener'))
|
||||
}).data('media-controls-disabled', selector.data('media-controls-disabled')).data('media-track-opener', selector.data('media-track-opener'))
|
||||
|
||||
// Embed any custom styles, applied to the .fader below selector
|
||||
if ("style" in options) {
|
||||
|
|
|
|||
|
|
@ -796,119 +796,198 @@
|
|||
|
||||
function _renderLocalMediaTracks() {
|
||||
|
||||
// is this the person who opened the recording?
|
||||
var isOpener = true;
|
||||
var localMediaMixers = _mixersForGroupId(ChannelGroupIds.MediaTrackGroup, MIX_MODES.MASTER);
|
||||
if(localMediaMixers.length == 0) {
|
||||
isOpener = false; // if we have PeerMediaTracks, then we didn't open the recording
|
||||
localMediaMixers = _mixersForGroupId(ChannelGroupIds.PeerMediaTrackGroup, MIX_MODES.MASTER);
|
||||
}
|
||||
// first gather all master mode media mixers and peer media mixers
|
||||
var localMediaMixers = _mixersForGroupId(ChannelGroupIds.MediaTrackGroup, MIX_MODES.MASTER);
|
||||
var peerLocalMediaMixers = _mixersForGroupId(ChannelGroupIds.PeerMediaTrackGroup, MIX_MODES.MASTER);
|
||||
|
||||
var recordedTracks = sessionModel.recordedTracks();
|
||||
// with mixer info, we use these to decide what kind of tracks are open in the backend
|
||||
|
||||
if(recordedTracks && localMediaMixers.length == 0) {
|
||||
// if we are the creator, then rather than raise an error, tell the server the recording is over.
|
||||
// this shoudl only happen if we get temporarily disconnected by forced reload, which isn't a very normal scenario
|
||||
if(sessionModel.getCurrentSession().claimed_recording_initiator_id == context.JK.userMe.id) {
|
||||
closeRecording();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// each mixer has a media_type field, which describes the type of media track it is.
|
||||
// * JamTrack
|
||||
// * BackingTrack
|
||||
// * RecordingTrack
|
||||
// * MetronomeTrack
|
||||
// * "" - adhoc track (not supported visually)
|
||||
|
||||
if(recordedTracks) {
|
||||
$('.session-recording-name').text(sessionModel.getCurrentSession().claimed_recording.name);
|
||||
// it is supposed to be the case that there are only one type of track open at a time, however, that's a business policy/logic
|
||||
// constraint; and may be buggy. **So, we should render whatever we have, so that it's obvious what's really going on.**
|
||||
|
||||
var noCorrespondingTracks = false;
|
||||
$.each(localMediaMixers, function(index, mixer) {
|
||||
var preMasteredClass = "";
|
||||
// find the track or tracks that correspond to the mixer
|
||||
var correspondingTracks = []
|
||||
$.each(recordedTracks, function(i, recordedTrack) {
|
||||
if(mixer.id.indexOf("L") == 0) {
|
||||
if(mixer.id.substring(1) == recordedTrack.client_track_id) {
|
||||
correspondingTracks.push(recordedTrack);
|
||||
}
|
||||
}
|
||||
else if(mixer.id.indexOf("C") == 0) {
|
||||
if(mixer.id.substring(1) == recordedTrack.client_id) {
|
||||
correspondingTracks.push(recordedTrack);
|
||||
preMasteredClass = "pre-mastered-track";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// this should not be possible
|
||||
alert("Invalid state: the recorded track had neither persisted_track_id or persisted_client_id");
|
||||
}
|
||||
});
|
||||
// so, let's group up all mixers by type, and then ask them to be rendered
|
||||
|
||||
if(correspondingTracks.length == 0) {
|
||||
noCorrespondingTracks = true;
|
||||
app.notify({
|
||||
title: "Unable to Open Recording",
|
||||
text: "Could not correlate server and client tracks",
|
||||
icon_url: "/assets/content/icon_alert_big.png"});
|
||||
return false;
|
||||
}
|
||||
|
||||
// prune found recorded tracks
|
||||
recordedTracks = $.grep(recordedTracks, function(value) {
|
||||
return $.inArray(value, correspondingTracks) < 0;
|
||||
});
|
||||
|
||||
var oneOfTheTracks = correspondingTracks[0];
|
||||
var instrumentIcon = context.JK.getInstrumentIcon45(oneOfTheTracks.instrument_id);
|
||||
var photoUrl = "/assets/content/icon_recording.png";
|
||||
|
||||
var name = oneOfTheTracks.user.name;
|
||||
if (!(name)) {
|
||||
name = oneOfTheTracks.user.first_name + ' ' + oneOfTheTracks.user.last_name;
|
||||
}
|
||||
var recordingTrackMixers = [];
|
||||
var backingTrackMixers = [];
|
||||
var jamTrackMixers = [];
|
||||
var metronomeTrackMixers = [];
|
||||
var adhocTrackMixers = [];
|
||||
|
||||
|
||||
// Default trackData to participant + no Mixer state.
|
||||
var trackData = {
|
||||
trackId: oneOfTheTracks.id,
|
||||
clientId: oneOfTheTracks.client_id,
|
||||
name: name,
|
||||
instrumentIcon: instrumentIcon,
|
||||
avatar: photoUrl,
|
||||
latency: "good",
|
||||
gainPercent: 0,
|
||||
muteClass: 'muted',
|
||||
mixerId: "",
|
||||
avatarClass : 'avatar-recording',
|
||||
preMasteredClass: preMasteredClass
|
||||
};
|
||||
function groupByType(mixers) {
|
||||
context._.each(mixers, function(mixer) {
|
||||
var mediaType = mixer.media_type;
|
||||
|
||||
var gainPercent = percentFromMixerValue(
|
||||
mixer.range_low, mixer.range_high, mixer.volume_left);
|
||||
var muteClass = "enabled";
|
||||
if (mixer.mute) {
|
||||
muteClass = "muted";
|
||||
}
|
||||
trackData.gainPercent = gainPercent;
|
||||
trackData.muteClass = muteClass;
|
||||
trackData.mixerId = mixer.id;
|
||||
trackData.vuMixerId = mixer.id;
|
||||
trackData.muteMixerId = mixer.id;
|
||||
if(mediaType == 'RecordingTrack') {
|
||||
recordingTrackMixers.push(mixer)
|
||||
}
|
||||
else if(mediaType == 'BackingTrack') {
|
||||
backingTrackMixers.push(mixer);
|
||||
}
|
||||
else if(mediaType == 'MetronomeTrack') {
|
||||
metronomeTrackMixers.push(mixer);
|
||||
}
|
||||
else if(mediaType == 'JamTrack') {
|
||||
jamTrackMixers.push(mixer);
|
||||
}
|
||||
else {
|
||||
adhocTrackMixers.push(mixer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if(sessionModel.isPersonalMixMode() || !isOpener) {
|
||||
trackData.recordingDisabled = true;
|
||||
trackData.recordingOpener = isOpener;
|
||||
}
|
||||
_addMediaTrack(trackData);
|
||||
});
|
||||
groupByType(localMediaMixers);
|
||||
groupByType(peerLocalMediaMixers);
|
||||
|
||||
if(!noCorrespondingTracks && recordedTracks.length > 0) {
|
||||
logger.error("unable to find all recorded tracks against client tracks");
|
||||
app.notify({title:"All tracks not found",
|
||||
text: "Some tracks in the recording are not present in the playback",
|
||||
icon_url: "/assets/content/icon_alert_big.png"})
|
||||
}
|
||||
}
|
||||
if(recordingTrackMixers.length > 0) {
|
||||
renderRecordingTracks(recordingTrackMixers)
|
||||
}
|
||||
if(backingTrackMixers.length > 0) {
|
||||
renderBackingTracks(backingTrackMixers)
|
||||
}
|
||||
if(jamTrackMixers.length > 0) {
|
||||
renderJamTracks(jamTrackMixers);
|
||||
}
|
||||
if(metronomeTrackMixers.length > 0) {
|
||||
renderMetronomeTracks(jamTrackMixers);
|
||||
}
|
||||
if(adhocTrackMixers.length > 0) {
|
||||
logger.warn("some tracks are open that we don't know how to show")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function renderBackingTracks(backingTrackMixers) {
|
||||
logger.error("do not know how to draw backing tracks yet")
|
||||
}
|
||||
|
||||
function renderJamTracks(jamTrackMixers) {
|
||||
logger.error("do not know how to draw jam tracks yet")
|
||||
}
|
||||
|
||||
function renderMetronomeTracks(metronomeTrackMixers) {
|
||||
logger.error("do not know how to draw metronome tracks yet")
|
||||
}
|
||||
|
||||
|
||||
function renderRecordingTracks(recordingMixers) {
|
||||
// get the server's info for the recording
|
||||
var recordedTracks = sessionModel.recordedTracks();
|
||||
|
||||
if(recordedTracks && recordingMixers.length == 0) {
|
||||
// if we are the creator, then rather than raise an error, tell the server the recording is over.
|
||||
// this shoudl only happen if we get temporarily disconnected by forced reload, which isn't a very normal scenario
|
||||
if(sessionModel.getCurrentSession().claimed_recording_initiator_id == context.JK.userMe.id) {
|
||||
closeRecording();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// pluck the 1st mixer, and assume that all other mixers in this group are of the same type (between Local vs Peer)
|
||||
// if it's a locally opened track (MediaTrackGroup), then we can say this person is the opener
|
||||
|
||||
var isOpener = recordingMixers[0].group_id == ChannelGroupIds.MediaTrackGroup;
|
||||
|
||||
// using the server's info in conjuction with the client's, draw the recording tracks
|
||||
if(recordedTracks) {
|
||||
$('.session-recording-name').text(sessionModel.getCurrentSession().claimed_recording.name);
|
||||
|
||||
var noCorrespondingTracks = false;
|
||||
$.each(recordingMixers, function(index, mixer) {
|
||||
var preMasteredClass = "";
|
||||
// find the track or tracks that correspond to the mixer
|
||||
var correspondingTracks = []
|
||||
$.each(recordedTracks, function(i, recordedTrack) {
|
||||
if(mixer.id.indexOf("L") == 0) {
|
||||
if(mixer.id.substring(1) == recordedTrack.client_track_id) {
|
||||
correspondingTracks.push(recordedTrack);
|
||||
}
|
||||
}
|
||||
else if(mixer.id.indexOf("C") == 0) {
|
||||
if(mixer.id.substring(1) == recordedTrack.client_id) {
|
||||
correspondingTracks.push(recordedTrack);
|
||||
preMasteredClass = "pre-mastered-track";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// this should not be possible
|
||||
alert("Invalid state: the recorded track had neither persisted_track_id or persisted_client_id");
|
||||
}
|
||||
});
|
||||
|
||||
if(correspondingTracks.length == 0) {
|
||||
noCorrespondingTracks = true;
|
||||
app.notify({
|
||||
title: "Unable to Open Recording",
|
||||
text: "Could not correlate server and client tracks",
|
||||
icon_url: "/assets/content/icon_alert_big.png"});
|
||||
return false;
|
||||
}
|
||||
|
||||
// prune found recorded tracks
|
||||
recordedTracks = $.grep(recordedTracks, function(value) {
|
||||
return $.inArray(value, correspondingTracks) < 0;
|
||||
});
|
||||
|
||||
var oneOfTheTracks = correspondingTracks[0];
|
||||
var instrumentIcon = context.JK.getInstrumentIcon45(oneOfTheTracks.instrument_id);
|
||||
var photoUrl = "/assets/content/icon_recording.png";
|
||||
|
||||
var name = oneOfTheTracks.user.name;
|
||||
if (!(name)) {
|
||||
name = oneOfTheTracks.user.first_name + ' ' + oneOfTheTracks.user.last_name;
|
||||
}
|
||||
|
||||
// Default trackData to participant + no Mixer state.
|
||||
var trackData = {
|
||||
trackId: oneOfTheTracks.id,
|
||||
clientId: oneOfTheTracks.client_id,
|
||||
name: name,
|
||||
instrumentIcon: instrumentIcon,
|
||||
avatar: photoUrl,
|
||||
latency: "good",
|
||||
gainPercent: 0,
|
||||
muteClass: 'muted',
|
||||
mixerId: "",
|
||||
avatarClass : 'avatar-recording',
|
||||
preMasteredClass: preMasteredClass
|
||||
};
|
||||
|
||||
var gainPercent = percentFromMixerValue(
|
||||
mixer.range_low, mixer.range_high, mixer.volume_left);
|
||||
var muteClass = "enabled";
|
||||
if (mixer.mute) {
|
||||
muteClass = "muted";
|
||||
}
|
||||
trackData.gainPercent = gainPercent;
|
||||
trackData.muteClass = muteClass;
|
||||
trackData.mixerId = mixer.id; // the master mixer controls the volume control for recordings (no personal controls in either master or personal mode)
|
||||
trackData.vuMixerId = mixer.id; // the master mixer controls the VUs for recordings (no personal controls in either master or personal mode)
|
||||
trackData.muteMixerId = mixer.id; // the master mixer controls the mute for recordings (no personal controls in either master or personal mode)
|
||||
|
||||
if(sessionModel.isPersonalMixMode() || !isOpener) {
|
||||
trackData.mediaControlsDisabled = true;
|
||||
trackData.mediaTrackOpener = isOpener;
|
||||
}
|
||||
_addRecordingTrack(trackData);
|
||||
});
|
||||
|
||||
if(!noCorrespondingTracks && recordedTracks.length > 0) {
|
||||
logger.error("unable to find all recorded tracks against client tracks");
|
||||
app.notify({title:"All tracks not found",
|
||||
text: "Some tracks in the recording are not present in the playback",
|
||||
icon_url: "/assets/content/icon_alert_big.png"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function trackMuteSelected(e, data) {
|
||||
var muteOption = data.muteOption; // muteOption is going to be either 'master' or 'personal'. We mute the correct one, based on track info
|
||||
|
||||
|
|
@ -1124,8 +1203,8 @@
|
|||
var vuRightSelector = trackSelector + " .track-vu-right";
|
||||
var faderSelector = trackSelector + " .track-gain";
|
||||
var $fader = $(faderSelector).attr('mixer-id', mixerId).data('groupId', groupId)
|
||||
if(track.recordingDisabled) {
|
||||
$fader.data('recording-disabled', true).data('recording-opener', track.recordingOpener) // this we be applied later to the fader handle $element
|
||||
if(track.mediaControlsDisabled) {
|
||||
$fader.data('media-controls-disabled', true).data('media-track-opener', track.mediaTrackOpener) // this we be applied later to the fader handle $element
|
||||
}
|
||||
var $track = $(trackSelector);
|
||||
// Set mixer-id attributes and render VU/Fader
|
||||
|
|
@ -1270,12 +1349,13 @@
|
|||
$closeButton.click(deleteTrack);
|
||||
}
|
||||
|
||||
// is this used?
|
||||
tracks[trackData.trackId] = new context.JK.SessionTrack(trackData.clientId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function _addMediaTrack(trackData) {
|
||||
function _addRecordingTrack(trackData) {
|
||||
var parentSelector = '#session-recordedtracks-container';
|
||||
var $destination = $(parentSelector);
|
||||
$('.session-recordings .when-empty').hide();
|
||||
|
|
@ -1294,13 +1374,13 @@
|
|||
var gainPercent = trackData.gainPercent || 0;
|
||||
var $track = connectTrackToMixer(trackSelector, trackData, trackData.mixerId, gainPercent, null);
|
||||
var $trackIconMute = $track.find('.track-icon-mute')
|
||||
if(trackData.recordingDisabled) {
|
||||
$trackIconMute.data('recording-disabled', true).data('recording-opener', trackData.recordingOpener)
|
||||
if(trackData.mediaControlsDisabled) {
|
||||
$trackIconMute.data('media-controls-disabled', true).data('media-track-opener', trackData.mediaTrackOpener)
|
||||
}
|
||||
// is this used?
|
||||
tracks[trackData.trackId] = new context.JK.SessionTrack(trackData.clientId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Will be called when fader changes. The fader id (provided at subscribe time),
|
||||
* the new value (0-100) and whether the fader is still being dragged are passed.
|
||||
|
|
@ -1451,10 +1531,10 @@
|
|||
// track icons have a special mute behavior
|
||||
if($control.is('.track-icon-mute')) {
|
||||
|
||||
var recordingDisabled = $control.data('recording-disabled');
|
||||
if(recordingDisabled) {
|
||||
var recordingOpener = $control.data('recording-opener');
|
||||
context.JK.prodBubble($control, 'recording-controls-disabled', {recordingOpener:recordingOpener}, {positions:['bottom'], offsetParent: $control.closest('.screen')})
|
||||
var mediaControlsDisabled = $control.data('media-controls-disabled');
|
||||
if(mediaControlsDisabled) {
|
||||
var mediaTrackOpener = $control.data('media-track-opener');
|
||||
context.JK.prodBubble($control, 'media-controls-disabled', {mediaTrackOpener:mediaTrackOpener}, {positions:['bottom'], offsetParent: $control.closest('.screen')})
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,39 @@
|
|||
top:-7px;
|
||||
left:5px;
|
||||
}
|
||||
|
||||
.open-media-file-header {
|
||||
font-size:16px;
|
||||
line-height:100%;
|
||||
margin:0;
|
||||
float:left;
|
||||
|
||||
img {
|
||||
position:relative;
|
||||
top:3px;
|
||||
}
|
||||
}
|
||||
|
||||
.open-media-file-options {
|
||||
font-size:16px;
|
||||
float:left;
|
||||
list-style: none !important;
|
||||
margin: 7px 0 0 7px !important;
|
||||
li {
|
||||
margin-bottom:5px !important;
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#track-settings {
|
||||
img {
|
||||
position:relative;
|
||||
top:3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -239,17 +272,19 @@ table.vu td {
|
|||
min-width:220px;
|
||||
}
|
||||
|
||||
#tracks .when-empty {
|
||||
#tracks .when-empty.livetracks {
|
||||
margin: 0px;
|
||||
padding:0px;
|
||||
display:block;
|
||||
padding-top: 125px;
|
||||
vertical-align:middle;
|
||||
text-align:center;
|
||||
font-weight: bold;
|
||||
}
|
||||
#tracks .when-empty.recordings {
|
||||
padding-top: 137px;
|
||||
//padding-top: 137px;
|
||||
text-align:left;
|
||||
padding-top:6px;
|
||||
margin:0;
|
||||
}
|
||||
|
||||
#tracks .when-empty a {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ require 'js_connect'
|
|||
|
||||
class VanillaForumsController < ApplicationController
|
||||
|
||||
|
||||
def log
|
||||
@log || Logging.logger[VanillaForumsController ]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -164,8 +164,8 @@
|
|||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-help-recording-controls-disabled">
|
||||
{% if(data.recordingOpener) { %}
|
||||
<script type="text/template" id="template-help-media-controls-disabled">
|
||||
{% if(data.mediaTrackOpener) { %}
|
||||
Switch <b>MIX:</b> to <b>Master</b> mode to have control over volume levels.
|
||||
{% } else { %}
|
||||
Only the person who opened the recording can control the volume levels.
|
||||
|
|
|
|||
|
|
@ -63,7 +63,8 @@
|
|||
<div class="session-mytracks">
|
||||
<h2>my tracks</h2>
|
||||
<div id="track-settings" class="session-add" style="display:block;" layout-link="configure-tracks">
|
||||
<%= image_tag "content/icon_settings_lg.png", {:width => 18, :height => 18} %> Settings
|
||||
<%= image_tag "content/icon_settings_lg.png", {:width => 18, :height => 18} %>
|
||||
<span>Settings</span>
|
||||
</div>
|
||||
|
||||
<div class="session-tracks-scroller">
|
||||
|
|
@ -86,11 +87,10 @@
|
|||
</div>
|
||||
<div class="session-tracks-scroller">
|
||||
<div id="session-livetracks-container">
|
||||
<p class="when-empty">
|
||||
No Live Tracks:<br/>
|
||||
<a layout-link="select-invites", href="#" id="session-invite-musicians2">Invite Other Musicians</a> to<br/>
|
||||
Add Live Tracks
|
||||
</p>
|
||||
<div class="when-empty livetracks">
|
||||
No other musicians <br/>
|
||||
are in your session
|
||||
</div>
|
||||
</div>
|
||||
<br clear="all" />
|
||||
<div class="recording" id="recording-start-stop">
|
||||
|
|
@ -112,9 +112,14 @@
|
|||
</div>
|
||||
<div class="session-tracks-scroller">
|
||||
<div id="session-recordedtracks-container">
|
||||
<p class="when-empty recordings">
|
||||
No Recordings:<br/><a href="#" id="open-a-recording">Open a Recording</a>
|
||||
</p>
|
||||
<div class="when-empty recordings">
|
||||
<span class="open-media-file-header"><%= image_tag "content/icon_folder.png", {width:22, height:20} %> Open:</span>
|
||||
<ul class="open-media-file-options">
|
||||
<li><a href="#" id="open-a-recording">Recording</a></li>
|
||||
<!--<li>JamTrack</li>
|
||||
<li>Audio File</li>-->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<br clear="all" />
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue