1127 lines
39 KiB
JavaScript
1127 lines
39 KiB
JavaScript
/*
|
|
Demo application using Ox.AudioPlayer.
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
Ox.load('UI', function() {
|
|
|
|
var app = {
|
|
$ui: {},
|
|
data: {},
|
|
site: {
|
|
listColumns: [
|
|
{
|
|
format: function(value, data) {
|
|
return Ox.Element('<img>')
|
|
.addClass('symbol')
|
|
.attr({src: Ox.UI.getImageURL(
|
|
'symbol' + Ox.toTitleCase(
|
|
value || (data.query ? 'find': 'click')
|
|
)
|
|
)});
|
|
},
|
|
id: 'icon',
|
|
title: 'icon',
|
|
visible: true,
|
|
width: 16
|
|
},
|
|
{
|
|
id: 'title',
|
|
title: 'Title',
|
|
visible: true,
|
|
width: 136
|
|
},
|
|
{
|
|
align: 'right',
|
|
id: 'items',
|
|
title: 'Items',
|
|
visible: true,
|
|
width: 40
|
|
}
|
|
],
|
|
lists: [
|
|
{icon: 'audio', id: 'Music', index: 0, items: 3, title: 'Music'},
|
|
{icon: 'playlist', id: 'Playing', index: 1, items: 0, title: 'Playing'}
|
|
],
|
|
sort: [
|
|
{key: 'artist', operator: '+'},
|
|
{key: 'year', operator: '+'},
|
|
{key: 'disc', operator: '+'},
|
|
{key: 'track', operator: '+'}
|
|
],
|
|
sums: ['duration', 'size'],
|
|
trackColumns: [
|
|
{
|
|
format: function(value) {
|
|
return value
|
|
? Ox.Element('<img>')
|
|
.addClass('symbol')
|
|
.attr({src: Ox.UI.getImageURL(
|
|
app.user.ui.paused
|
|
? 'symbolUnmute' : 'symbolMute'
|
|
)})
|
|
: Ox.Element();
|
|
},
|
|
id: 'playing',
|
|
removable: false,
|
|
title: 'Playing',
|
|
titleImage: 'mute',
|
|
visible: true,
|
|
width: 16
|
|
},
|
|
{
|
|
format: function(value) {
|
|
return value
|
|
? Ox.Element('<img>')
|
|
.addClass('symbol')
|
|
.attr({src: Ox.UI.getImageURL(
|
|
'symbolCheck'
|
|
)})
|
|
: Ox.Element();
|
|
},
|
|
id: 'checked',
|
|
removable: false,
|
|
title: 'Checked',
|
|
titleImage: 'check',
|
|
visible: true,
|
|
width: 16
|
|
},
|
|
{
|
|
format: function(value) {
|
|
return value
|
|
? Ox.Element('<img>')
|
|
.addClass('image')
|
|
.attr({src: value})
|
|
: Ox.Element()
|
|
},
|
|
id: 'artwork',
|
|
operator: '+',
|
|
title: 'Artwork',
|
|
titleImage: 'icon',
|
|
visible: true,
|
|
width: 16
|
|
},
|
|
{
|
|
align: 'right',
|
|
id: 'disc',
|
|
operator: '+',
|
|
title: 'Disc',
|
|
titleImage: 'circle',
|
|
width: 32
|
|
},
|
|
{
|
|
align: 'right',
|
|
id: 'track',
|
|
operator: '+',
|
|
title: 'Track',
|
|
titleImage: 'square',
|
|
width: 32
|
|
},
|
|
{
|
|
id: 'title',
|
|
operator: '+',
|
|
removable: false,
|
|
title: 'Title',
|
|
visible: true,
|
|
width: 192
|
|
},
|
|
{
|
|
id: 'artist',
|
|
operator: '+',
|
|
removable: false,
|
|
title: 'Artist',
|
|
visible: true,
|
|
width: 192
|
|
},
|
|
{
|
|
id: 'album',
|
|
operator: '+',
|
|
removable: false,
|
|
title: 'Album',
|
|
visible: true,
|
|
width: 192
|
|
},
|
|
{
|
|
align: 'right',
|
|
id: 'year',
|
|
operator: '+',
|
|
title: 'Year',
|
|
visible: true,
|
|
width: 64
|
|
},
|
|
{
|
|
align: 'right',
|
|
format: function(value) {
|
|
return Ox.formatDuration(value).substr(4);
|
|
},
|
|
id: 'duration',
|
|
operator: '-',
|
|
title: 'Time',
|
|
visible: true,
|
|
width: 64
|
|
},
|
|
{
|
|
align: 'right',
|
|
format: function(value) {
|
|
return Ox.formatValue(value, 'B');
|
|
},
|
|
id: 'size',
|
|
operator: '-',
|
|
title: 'Size',
|
|
visible: true,
|
|
width: 64
|
|
},
|
|
{
|
|
align: 'right',
|
|
format: function(value) {
|
|
return Math.round(value) + ' kbps'
|
|
},
|
|
id: 'bitrate',
|
|
operator: '-',
|
|
title: 'Bitrate',
|
|
visible: true,
|
|
width: 64
|
|
},
|
|
{
|
|
id: 'genre',
|
|
operator: '+',
|
|
title: 'Genre',
|
|
visible: true,
|
|
width: 128
|
|
}
|
|
]
|
|
},
|
|
ui: {},
|
|
user: {
|
|
lists: [
|
|
{
|
|
id: 'favorites',
|
|
index: 0,
|
|
items: 0,
|
|
title: 'Favorites',
|
|
type: 'static'
|
|
},
|
|
{
|
|
id: 'hip-hop',
|
|
index: 1,
|
|
items: 1,
|
|
query: {
|
|
conditions: [
|
|
{key: 'genre', operator: '==', value: 'Hip-Hop'}
|
|
],
|
|
operator: '&'
|
|
},
|
|
title: 'Hip-Hop'
|
|
}
|
|
],
|
|
ui: {
|
|
artwork: 'selected',
|
|
coverSize: 64,
|
|
list: 'Music',
|
|
paused: true,
|
|
query: {
|
|
conditions: [],
|
|
operator: '&',
|
|
},
|
|
selectedAlbum: [],
|
|
selectedArtist: [],
|
|
selectedTrack: [],
|
|
showSidebar: true,
|
|
sidebarSize: 192,
|
|
track: 0,
|
|
tracklistSize: 256,
|
|
view: 'tracks'
|
|
}
|
|
},
|
|
utils: {}
|
|
};
|
|
|
|
app.user.ui.sort = Ox.clone(app.site.sort, true);
|
|
|
|
app.load = function() {
|
|
Ox.getJSON('json/music.json', function(data) {
|
|
app.data.tracks = data;
|
|
app.data.artists = app.utils.getArtists();
|
|
app.data.albums = app.utils.getAlbums();
|
|
app.$ui.appPanel = app.ui.appPanel().appendTo(Ox.$body);
|
|
Ox.$window.bind({resize: app.utils.resizeWindow});
|
|
});
|
|
};
|
|
|
|
app.UI = (function() {
|
|
var that = {};
|
|
that.set = function() {
|
|
var args = Ox.makeObject(arguments),
|
|
keys = [],
|
|
previousUI = Ox.clone(app.user.ui, true);
|
|
Ox.forEach(args, function(value, key) {
|
|
if (!Ox.isEqual(value, previousUI[key])) {
|
|
app.user.ui[key] = value;
|
|
keys.push(key);
|
|
}
|
|
});
|
|
keys.forEach(function(key) {
|
|
var data = {
|
|
previousValue: previousUI[key],
|
|
value: app.user.ui[key]
|
|
}
|
|
Ox.print('ui_' + key.toLowerCase(), JSON.stringify(app.user.ui[key]))
|
|
Ox.forEach(app.$ui, function($elements) {
|
|
Ox.makeArray($elements).forEach(function($element) {
|
|
$element.triggerEvent('ui_' + key.toLowerCase(), data);
|
|
});
|
|
});
|
|
});
|
|
};
|
|
return that;
|
|
}());
|
|
|
|
app.ui.appPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{element: app.$ui.mainMenu = app.ui.mainMenu(), size: 20},
|
|
{element: app.$ui.mainPanel = app.ui.mainPanel()}
|
|
],
|
|
orientation: 'vertical'
|
|
});
|
|
};
|
|
|
|
app.ui.mainMenu = function() {
|
|
return Ox.MainMenu({
|
|
menus: [
|
|
{
|
|
id: '0xcd',
|
|
title: '0xCD',
|
|
items: [
|
|
{id: 'about', title: 'About 0xCD'}
|
|
]
|
|
}
|
|
]
|
|
})
|
|
.bindEvent({
|
|
click: function(data) {
|
|
if (data.id == 'about') {
|
|
app.$ui.aboutDialog = (
|
|
app.$ui.aboutDialog || app.ui.aboutDialog()
|
|
).open();
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.aboutDialog = function() {
|
|
var $element = Ox.Dialog({
|
|
buttons: [
|
|
Ox.Button({
|
|
id: 'close',
|
|
title: 'Close'
|
|
})
|
|
.bindEvent({
|
|
click: function() {
|
|
$element.close();
|
|
}
|
|
})
|
|
],
|
|
content: Ox.Element()
|
|
.html('Audio Player Example'),
|
|
height: 256,
|
|
keys: {enter: 'close', escape: 'close'},
|
|
title: 'About 0xCD',
|
|
width: 512
|
|
});
|
|
return $element;
|
|
};
|
|
|
|
app.ui.mainPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{element: app.ui.$toolbar = app.ui.toolbar(), size: 39},
|
|
{element: app.ui.$bothPanel = app.ui.bothPanel()}
|
|
],
|
|
orientation: 'vertical'
|
|
});
|
|
};
|
|
|
|
app.ui.toolbar = function() {
|
|
return Ox.Bar({size: 39})
|
|
.attr({id: 'toolbar'})
|
|
.append(app.$ui.audioPlayer = app.ui.audioPlayer())
|
|
.append(app.$ui.viewLabel = app.ui.viewLabel())
|
|
.append(app.$ui.viewButtons = app.ui.viewButtons())
|
|
.append(app.$ui.findSelect = app.ui.findSelect())
|
|
.append(app.$ui.findLabel = app.ui.findLabel())
|
|
.append(app.$ui.findInput = app.ui.findInput());
|
|
};
|
|
|
|
app.ui.audioPlayer = function() {
|
|
return Ox.AudioPlayer({
|
|
audio: app.data.tracks,
|
|
paused: true,
|
|
width: window.innerWidth - 190
|
|
})
|
|
.css({left: '4px', top: '4px'})
|
|
.bindEvent({
|
|
paused: function(data) {
|
|
var id = app.data.tracks[app.user.ui.track].file
|
|
app.user.ui.paused = data.paused;
|
|
app.$ui.trackList.value(id, 'playing', false);
|
|
app.$ui.trackList.value(id, 'playing', true);
|
|
},
|
|
track: function(data) {
|
|
var id = app.data.tracks[app.user.ui.track].file
|
|
app.$ui.trackList.value(id, 'playing', false);
|
|
app.user.ui.track = data.track;
|
|
$app.$ui.trackList.value(id, 'playing', true);
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.viewLabel = function() {
|
|
return Ox.Label({
|
|
textAlign: 'center',
|
|
title: 'Tracks',
|
|
width: 50
|
|
})
|
|
.attr({id: 'viewLabel'});
|
|
};
|
|
|
|
app.ui.viewButtons = function() {
|
|
return Ox.ButtonGroup({
|
|
buttons: [
|
|
{id: 'tracks', title: 'list', tooltip: 'View Tracks'},
|
|
{id: 'albums', title: 'grid', tooltip: 'View Albums'},
|
|
{id: 'artists', title: 'columns', tooltip: 'View Artists'}
|
|
],
|
|
max: 1,
|
|
min: 1,
|
|
selectable: true,
|
|
type: 'image'
|
|
})
|
|
.attr({id: 'viewButtons'})
|
|
.css({
|
|
position: 'absolute',
|
|
right: '136px',
|
|
top: '19px'
|
|
})
|
|
.bindEvent({
|
|
change: function(data) {
|
|
app.user.ui.view = data.value;
|
|
app.$ui.viewLabel.options({title: Ox.toTitleCase(app.user.ui.view)});
|
|
app.$ui.rightPanel.replaceElement(0, app.$ui.musicPanel = app.ui.musicPanel());
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.findSelect = function() {
|
|
return Ox.Select({
|
|
items: [
|
|
{id: 'all', title: 'Find: All'},
|
|
{id: 'tracks', title: 'Find: Tracks'},
|
|
{id: 'artists', title: 'Find: Artists'},
|
|
{id: 'albums', title: 'Find: Albums'}
|
|
],
|
|
overlap: 'left',
|
|
type: 'image'
|
|
})
|
|
.attr({id: 'findSelect'})
|
|
.bindEvent({
|
|
change: function(data) {
|
|
app.$ui.findLabel.options({title: data.title});
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.findLabel = function() {
|
|
return Ox.Label({
|
|
title: 'Find: All',
|
|
width: 112
|
|
})
|
|
.attr({id: 'findLabel'});
|
|
};
|
|
|
|
app.ui.findInput = function() {
|
|
return Ox.Input({
|
|
clear: true,
|
|
width: 128
|
|
})
|
|
.attr({id: 'findInput'});
|
|
};
|
|
|
|
app.ui.bothPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{
|
|
collapsible: true,
|
|
element: app.$ui.leftPanel = app.ui.leftPanel(),
|
|
resizable: true,
|
|
resize: [128, 192, 256, 320, 384],
|
|
size: app.user.ui.sidebarSize
|
|
},
|
|
{
|
|
element: app.$ui.rightPanel = app.ui.rightPanel()
|
|
}
|
|
],
|
|
orientation: 'horizontal'
|
|
});
|
|
}
|
|
|
|
app.ui.leftPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{
|
|
element: app.$ui.listsPanel = app.ui.listsPanel()
|
|
},
|
|
{
|
|
collapsible: true,
|
|
element: app.$ui.artworkPanel = app.ui.artworkPanel(),
|
|
size: app.user.ui.sidebarSize + 16
|
|
}
|
|
],
|
|
orientation: 'vertical'
|
|
})
|
|
.bindEvent({
|
|
resize: function(data) {
|
|
app.user.ui.sidebarSize = data.size;
|
|
[app.$ui.siteLists, app.$ui.userLists].forEach(function($list) {
|
|
$list.setColumnWidth('title', app.user.ui.sidebarSize - 56);
|
|
});
|
|
app.$ui.listsList
|
|
app.$ui.leftPanel.size(1, app.user.ui.sidebarSize + 16);
|
|
app.$ui.artwork.css({
|
|
width: app.user.ui.sidebarSize + 'px',
|
|
height: app.user.ui.sidebarSize + 'px'
|
|
});
|
|
//$musicList.size();
|
|
}
|
|
})
|
|
};
|
|
|
|
app.ui.listsPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{
|
|
element: app.$ui.siteLists = app.ui.siteLists(),
|
|
size: app.site.lists.length * 16
|
|
},
|
|
{
|
|
element: app.$ui.userLists = app.ui.userLists()
|
|
}
|
|
],
|
|
orientation: 'vertical'
|
|
});
|
|
};
|
|
|
|
app.ui.siteLists = function() {
|
|
var $element = Ox.TableList({
|
|
columns: app.site.listColumns,
|
|
items: app.site.lists,
|
|
max: 1,
|
|
selected: [app.user.ui.list],
|
|
sort: [{key: 'index', operator: '+'}],
|
|
unique: 'id'
|
|
})
|
|
.bindEvent({
|
|
select: function(data) {
|
|
app.UI.set({list: data.ids[0] || app.site.lists[0].id});
|
|
},
|
|
selectafter: function() {
|
|
app.UI.set({list: app.user.lists[0].id});
|
|
app.$ui.userLists.gainFocus();
|
|
},
|
|
ui_list: function(data) {
|
|
$element.options({
|
|
selected: data.value[0] == data.value[0].toUpperCase()
|
|
? [data.value] : []
|
|
});
|
|
}
|
|
});
|
|
$element.update = function() {
|
|
return $element.setColumnWidth('title', app.user.ui.sidebarSize - 56);
|
|
};
|
|
return $element.update();
|
|
};
|
|
|
|
app.ui.userLists = function() {
|
|
var $element = Ox.TableList({
|
|
columns: app.site.listColumns,
|
|
items: app.user.lists,
|
|
keys: ['query'],
|
|
max: 1,
|
|
selected: [app.user.ui.list],
|
|
sort: [{key: 'index', operator: '+'}],
|
|
sortable: true,
|
|
unique: 'id'
|
|
})
|
|
.bindEvent({
|
|
move: function(data) {
|
|
// ...
|
|
},
|
|
select: function(data) {
|
|
app.UI.set({list: data.ids[0] || app.site.lists[0].id});
|
|
},
|
|
selectbefore: function() {
|
|
app.UI.set({list: Ox.last(app.site.lists).id});
|
|
app.$ui.siteLists.gainFocus();
|
|
},
|
|
ui_list: function(data) {
|
|
$element.options({
|
|
selected: data.value[0] == data.value[0].toLowerCase()
|
|
? [data.value] : []
|
|
});
|
|
}
|
|
});
|
|
$element.update = function() {
|
|
return $element.setColumnWidth('title', app.user.ui.sidebarSize - 56);
|
|
};
|
|
return $element.update();
|
|
};
|
|
|
|
app.ui.artworkPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{element: app.$ui.artworkbar = app.ui.artworkbar(), size: 16},
|
|
{element: app.$ui.artwork = app.ui.artwork()}
|
|
],
|
|
orientation: 'vertical'
|
|
});
|
|
};
|
|
|
|
app.ui.artworkbar = function() {
|
|
return Ox.Bar({size: 16})
|
|
.append(app.$ui.artworkText = app.ui.artworkText())
|
|
.bindEvent({
|
|
anyclick: function() {
|
|
app.UI.set({
|
|
artwork: app.user.ui.artwork == 'playing'
|
|
? 'selected' : 'playing'
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.artworkText = function() {
|
|
var $element = Ox.Element()
|
|
.attr({id: 'artworkText'})
|
|
.bindEvent({
|
|
ui_artwork: function() {
|
|
$element.update();
|
|
}
|
|
});
|
|
$element.update = function() {
|
|
$element.html(
|
|
app.user.ui.artwork == 'playing'
|
|
? 'Now Playing' : 'Selected Item'
|
|
);
|
|
return $element;
|
|
};
|
|
return $element.update();
|
|
};
|
|
|
|
app.ui.artwork = function() {
|
|
var $element = Ox.Element('<img>')
|
|
.attr({src: app.data.tracks[0].artwork})
|
|
.bindEvent({
|
|
ui_selectedalbum: function(data) {
|
|
if (app.user.ui.artwork == 'selected') {
|
|
$element.attr({
|
|
src: data.value.length
|
|
? Ox.getObjectById(app.data.albums, data.value[0]).artwork
|
|
: ''
|
|
});
|
|
}
|
|
},
|
|
ui_selectedartist: function(data) {
|
|
if (app.user.ui.artwork == 'selected') {
|
|
$element.attr({
|
|
src: data.value.length
|
|
? Ox.getObjectById(app.data.artists, data.value[0]).artwork
|
|
: ''
|
|
});
|
|
}
|
|
},
|
|
ui_selectedtrack: function(data) {
|
|
if (app.user.ui.artwork == 'selected') {
|
|
$element.attr({
|
|
src: data.value.length
|
|
? Ox.getObjectById(app.data.tracks, data.value[0]).artwork
|
|
: ''
|
|
});
|
|
}
|
|
}
|
|
});
|
|
$element.update = function() {
|
|
$element.css({
|
|
width: app.user.ui.sidebarSize + 'px',
|
|
height: app.user.ui.sidebarSize + 'px'
|
|
});
|
|
return $element;
|
|
};
|
|
return $element.update();
|
|
};
|
|
|
|
app.ui.rightPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{element: app.$ui.musicPanel = app.ui.musicPanel()},
|
|
{element: app.$ui.statusbar = app.ui.statusbar(), size: 16}
|
|
],
|
|
orientation: 'vertical'
|
|
});
|
|
};
|
|
|
|
app.ui.musicPanel = function() {
|
|
return app.ui[app.user.ui.view + 'Panel']();
|
|
};
|
|
|
|
app.ui.tracksPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{
|
|
collapsible: true,
|
|
element: app.$ui.albumBrowser = app.ui.albumBrowser(),
|
|
size: 112 + Ox.UI.SCROLLBAR_SIZE
|
|
},
|
|
{
|
|
element: app.$ui.trackList = app.ui.trackList()
|
|
}
|
|
],
|
|
orientation: 'vertical'
|
|
});
|
|
};
|
|
|
|
app.ui.albumBrowser = function() {
|
|
var $element = Ox.IconList({
|
|
fixedRatio: 1,
|
|
item: function(data, sort, size) {
|
|
return {
|
|
height: size,
|
|
id: data.id,
|
|
info: data.year,
|
|
title: [data.artist, data.title].join(' — '),
|
|
url: data.artwork,
|
|
width: size
|
|
};
|
|
},
|
|
items: app.data.albums,
|
|
max: 1,
|
|
orientation: 'horizontal',
|
|
pageLength: 100,
|
|
query: {conditions: [], operator: '&'},
|
|
selected: [],
|
|
size: 64,
|
|
sort: [{key: 'index', operator: '+'}],
|
|
unique: 'id'
|
|
})
|
|
.bindEvent({
|
|
ui_sort: function() {
|
|
$element.update();
|
|
}
|
|
});
|
|
$element.update = function() {
|
|
app.utils.getTrackAlbums(function(albums) {
|
|
$element.options({items: albums});
|
|
});
|
|
return $element;
|
|
}
|
|
return $element;
|
|
};
|
|
|
|
app.ui.trackList = function() {
|
|
return Ox.TableList({
|
|
columns: app.site.trackColumns,
|
|
columnsMovable: true,
|
|
columnsRemovable: true,
|
|
columnsResizable: true,
|
|
columnsVisible: true,
|
|
items: app.data.tracks,
|
|
scrollbarVisible: true,
|
|
sort: Ox.clone(app.user.ui.sort, true),
|
|
sums: app.site.sums,
|
|
unique: 'id'
|
|
})
|
|
.bindEvent({
|
|
init: function(data) {
|
|
app.$ui.statusText.update(data);
|
|
app.utils.getTrackAlbums(function(data) {
|
|
// ...
|
|
});
|
|
},
|
|
open: function(data) {
|
|
var file = data.ids[0],
|
|
id = app.data.tracks[app.user.ui.track].id,
|
|
index = Ox.getIndexById(app.data.tracks, id);
|
|
if (index == app.user.ui.track) {
|
|
app.$ui.trackList.value(id, 'playing', true);
|
|
app.$ui.audioPlayer.options({paused: false, position: 0});
|
|
} else {
|
|
app.$ui.trackList.value(id, 'playing', false);
|
|
app.user.ui.track = index;
|
|
app.$ui.audioPlayer.options({paused: false, track: app.user.ui.track});
|
|
app.$ui.trackList.value(id, 'playing', true);
|
|
}
|
|
},
|
|
openpreview: function(data) {
|
|
app.user.ui.paused = !app.user.ui.paused;
|
|
app.$ui.audioPlayer.options({paused: app.user.ui.paused});
|
|
app.$ui.trackList.closePreview();
|
|
},
|
|
select: function(data) {
|
|
app.UI.set({selectedTrack: data.ids});
|
|
},
|
|
sort: function(data) {
|
|
app.UI.set({sort: [data]});
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.albumsPanel = function() {
|
|
return Ox.SplitPanel({
|
|
elements: [
|
|
{
|
|
element: app.$ui.albumList = app.ui.albumList()
|
|
},
|
|
{
|
|
element: app.$ui.trackBrowser = app.ui.trackBrowser(),
|
|
resizable: true,
|
|
resize: [192, 256, 320],
|
|
size: app.user.ui.tracklistSize
|
|
}
|
|
],
|
|
orientation: 'horizontal'
|
|
});
|
|
};
|
|
|
|
app.ui.albumList = function() {
|
|
return Ox.IconList({
|
|
fixedRatio: 1,
|
|
item: function(data, sort, size) {
|
|
var key = Ox.contains(['artist', 'title'], sort[0].key)
|
|
? 'year' : sort[0].key,
|
|
column = Ox.getObjectById(app.site.trackColumns, key),
|
|
info = (column.format || Ox.identity)(data[key]);
|
|
return {
|
|
height: size,
|
|
id: data.id,
|
|
info: info,
|
|
title: [data.artist, data.title].join(' — '),
|
|
url: data.artwork,
|
|
width: size
|
|
};
|
|
},
|
|
items: app.data.albums,
|
|
pageLength: 120,
|
|
query: {conditions: [], operator: '&'},
|
|
selected: [],
|
|
size: 128,
|
|
sort: Ox.clone(app.user.ui.sort, true),
|
|
unique: 'id'
|
|
})
|
|
.bindEvent({
|
|
select: function(data) {
|
|
app.UI.set({selectedAlbum: data.ids});
|
|
},
|
|
openpreview: function() {
|
|
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.trackBrowser = function() {
|
|
return Ox.TableList({
|
|
columns: [
|
|
Ox.getObjectById(app.site.trackColumns, 'playing'),
|
|
Ox.getObjectById(app.site.trackColumns, 'checked'),
|
|
Ox.getObjectById(app.site.trackColumns, 'artwork'),
|
|
Ox.extend(
|
|
Ox.getObjectById(app.site.trackColumns, 'track'),
|
|
{visible: true}
|
|
),
|
|
Ox.extend(
|
|
Ox.getObjectById(app.site.trackColumns, 'title'),
|
|
{width: app.user.ui.tracklistSize - 144 - Ox.UI.SCROLLBAR_SIZE}
|
|
),
|
|
Ox.getObjectById(app.site.trackColumns, 'duration')
|
|
],
|
|
items: app.data.tracks,
|
|
query: {conditions: [], operator: '&'},
|
|
scrollbarVisible: true,
|
|
selected: [],
|
|
sort: Ox.clone(app.site.sort, true),
|
|
unique: 'id'
|
|
})
|
|
.bindEvent({
|
|
resize: function(data) {
|
|
app.user.ui.tracklistSize = data.size;
|
|
app.$ui.trackBrowser.setColumnWidth(
|
|
'title', app.user.ui.tracklistSize - 144 - Ox.UI.SCROLLBAR_SIZE
|
|
);
|
|
},
|
|
ui_selectedalbum: function(data) {
|
|
app.$ui.trackBrowser.options({
|
|
items: data.value.length ? Ox.flatten(
|
|
data.value.map(function(id) {
|
|
return Ox.getObjectById(app.data.albums, id).items;
|
|
})
|
|
) : []
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.artistsPanel = function() {
|
|
return Ox.ColumnList({
|
|
columns: [
|
|
{
|
|
id: 'artists',
|
|
item: function(data, width) {
|
|
data.artwork = data.artwork || '';
|
|
data.years = data.years || [];
|
|
var $item = $('<div>')
|
|
.addClass('item')
|
|
.css({width: width + 'px'});
|
|
$('<img>')
|
|
.addClass('itemIcon')
|
|
.attr({src: data.artwork})
|
|
.appendTo($item);
|
|
$('<div>')
|
|
.addClass('itemTitle')
|
|
.css({width: width - 36 + 'px'})
|
|
.html(data.name ? data.name : '')
|
|
.appendTo($item);
|
|
$('<div>')
|
|
.addClass('itemInfo OxLight')
|
|
.css({width: width - 36 + 'px'})
|
|
.html(
|
|
[
|
|
data.years.join('-'),
|
|
Ox.formatCount(data.albums, 'album'),
|
|
Ox.formatCount(data.tracks, 'track'),
|
|
Ox.formatDuration(data.duration),
|
|
Ox.formatValue(data.size, 'B')
|
|
].join(' — ')
|
|
)
|
|
.appendTo($item);
|
|
return $item;
|
|
},
|
|
itemHeight: 32,
|
|
keys: ['albums', 'artwork', 'duration', 'name', 'size', 'tracks', 'years']
|
|
},
|
|
{
|
|
id: 'albums',
|
|
item: function(data, width) {
|
|
data.artwork = data.artwork || '';
|
|
data.tracks = data.tracks || [{duration: 0}];
|
|
data.year = data.year || '????';
|
|
var $item = $('<div>')
|
|
.addClass('item')
|
|
.css({width: width + 'px'});
|
|
$('<img>')
|
|
.addClass('itemIcon')
|
|
.attr({src: data.artwork})
|
|
.appendTo($item);
|
|
$('<div>')
|
|
.addClass('itemTitle')
|
|
.css({width: width - 36 + 'px'})
|
|
.html(data.title ? data.title : '')
|
|
.appendTo($item);
|
|
$('<div>')
|
|
.addClass('itemInfo OxLight')
|
|
.css({width: width - 36 + 'px'})
|
|
.html(
|
|
[
|
|
data.year,
|
|
Ox.formatCount(data.tracks, 'track'),
|
|
Ox.formatDuration(data.duration),
|
|
Ox.formatValue(data.size, 'B')
|
|
].join(' — ')
|
|
)
|
|
.appendTo($item);
|
|
return $item;
|
|
},
|
|
itemHeight: 32,
|
|
keys: ['artwork', 'duration', 'size', 'title', 'tracks', 'year']
|
|
},
|
|
{
|
|
id: 'tracks',
|
|
item: function(data, width) {
|
|
var $item = $('<div>')
|
|
.addClass('item')
|
|
.css({width: width + 'px'});
|
|
$('<img>')
|
|
.addClass('itemIcon')
|
|
.attr({src: data.artwork})
|
|
.appendTo($item);
|
|
$('<div>')
|
|
.addClass('itemTitle')
|
|
.css({width: width - 36 + 'px'})
|
|
.html(data.title ? data.title : '')
|
|
.appendTo($item);
|
|
$('<div>')
|
|
.addClass('itemInfo OxLight')
|
|
.css({width: width - 36 + 'px'})
|
|
.html(
|
|
[
|
|
Ox.formatDuration(data.duration),
|
|
Ox.formatValue(data.size, 'B'),
|
|
Math.round(data.bitrate) + ' kbps'
|
|
].join(' — ')
|
|
)
|
|
.appendTo($item);
|
|
return $item;
|
|
},
|
|
itemHeight: 32,
|
|
keys: ['artwork', 'bitrate', 'checked', 'duration', 'playing', 'size', 'title']
|
|
}
|
|
],
|
|
items: app.data.artists,
|
|
list: 'custom',
|
|
width: window.innerWidth - app.user.ui.sidebarSize - 1
|
|
})
|
|
.bindEvent({
|
|
resize: function(data) {
|
|
$panel.options({width: data.size})
|
|
},
|
|
select: function(data) {
|
|
app.UI.set(
|
|
'selected' + Ox.toTitleCase(data.id.slice(0, -1)),
|
|
data.ids
|
|
);
|
|
}
|
|
});
|
|
};
|
|
|
|
app.ui.statusbar = function() {
|
|
return Ox.Bar({size: 16})
|
|
.append(app.$ui.statusText = app.ui.statusText());
|
|
};
|
|
|
|
app.ui.statusText = function() {
|
|
var $element = Ox.Element().attr({id: 'statusText'});
|
|
$element.update = function(data) {
|
|
return $element.html(
|
|
data ? [
|
|
Ox.formatCount(data.items, 'track'),
|
|
Ox.formatDuration(data.duration),
|
|
Ox.formatValue(data.size, 'B')
|
|
].join(' — ') : 'Loading...'
|
|
);
|
|
};
|
|
return $element.update();
|
|
};
|
|
|
|
app.utils.getAlbums = function() {
|
|
var albums = []
|
|
app.data.artists.forEach(function(artist) {
|
|
artist.items.forEach(function(album) {
|
|
albums.push(Ox.extend(album, {artist: artist.name}));
|
|
});
|
|
});
|
|
return albums;
|
|
};
|
|
|
|
app.utils.getArtists = function() {
|
|
var artists = [], tree = {};
|
|
app.data.tracks.forEach(function(track, index) {
|
|
var artist = track.artist,
|
|
album = track.year + ' ' + track.album,
|
|
title = Ox.pad(track.disc, 2) + '\n' + Ox.pad(track.track, 2)
|
|
+ '\n' + track.title;
|
|
if (!tree[artist]) {
|
|
tree[artist] = {};
|
|
}
|
|
if (!tree[artist][album]) {
|
|
tree[artist][album] = {};
|
|
}
|
|
if (!tree[artist][album][title]) {
|
|
tree[artist][album][title] = track;
|
|
}
|
|
});
|
|
Ox.forEach(tree, function(albums, artist) {
|
|
artist = {
|
|
albums: Ox.len(albums),
|
|
artwork: 'http://0x2620.org/music/' + artist + '/artwork.png',
|
|
id: artist,
|
|
items: [],
|
|
name: artist
|
|
};
|
|
Ox.forEach(albums, function(tracks, id) {
|
|
var title = id.substr(5),
|
|
year = id.substr(0, 4);
|
|
artist.items.push({
|
|
artwork: tracks[Object.keys(tracks)[0]].artwork,
|
|
duration: Ox.values(tracks).reduce(function(r, v, i) {
|
|
return r + v.duration;
|
|
}, 0),
|
|
id: [artist.id, year + ' ' + title].join('\n'),
|
|
items: [],
|
|
size: Ox.values(tracks).reduce(function(r, v, i) {
|
|
return r + v.size;
|
|
}, 0),
|
|
title: title,
|
|
tracks: Ox.len(tracks),
|
|
year: year
|
|
});
|
|
Ox.forEach(tracks, function(track, id) {
|
|
artist.items[artist.items.length - 1].items.push({
|
|
artist: track.artist,
|
|
artwork: track.artwork,
|
|
bitrate: track.bitrate,
|
|
checked: track.checked,
|
|
disc: track.disc,
|
|
duration: track.duration,
|
|
id: id,
|
|
genre: track.genre,
|
|
playing: track.playing,
|
|
size: track.size,
|
|
title: track.title,
|
|
track: track.track
|
|
});
|
|
});
|
|
});
|
|
['duration', 'size', 'tracks'].forEach(function(key) {
|
|
artist[key] = artist.items.reduce(function(r, v, i) {
|
|
return r + v[key];
|
|
}, 0);
|
|
})
|
|
artist.years = Ox.unique(artist.items.map(function(item) {
|
|
return item.year;
|
|
})).sort();
|
|
artist.years = [artist.years[0]].concat(
|
|
artist.years.length > 1
|
|
? [artist.years[artist.years.length - 1]]
|
|
: []
|
|
);
|
|
artists.push(artist);
|
|
});
|
|
return artists;
|
|
};
|
|
|
|
app.utils.getTrackAlbums = function(callback) {
|
|
app.$ui.trackList.api({
|
|
keys: ['id'],
|
|
query: app.user.ui.query,
|
|
sort: app.user.ui.sort
|
|
}, function(result) {
|
|
callback(result.data.items.reduce(function(r, v, i) {
|
|
var albumId = v.id.split('\n').slice(0, 2).join('\n'),
|
|
last = Ox.last(r);
|
|
return last && last.albumId == albumId ? r : r.concat(
|
|
Ox.extend(
|
|
Ox.clone(Ox.getObjectById(app.data.albums, albumId)),
|
|
{albumId: albumId, id: v.id, index: r.length}
|
|
)
|
|
);
|
|
}, []));
|
|
});
|
|
};
|
|
|
|
app.utils.resizeWindow = function() {
|
|
|
|
};
|
|
|
|
app.load();
|
|
|
|
window.app = app;
|
|
|
|
});
|