diff --git a/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js index 8949ce5..ebf699b 100644 --- a/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js +++ b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js @@ -83,6 +83,7 @@ }.bind( { stage: source + , id: data.id , href: data.src_location , hash: data.hash , author: data.author @@ -307,7 +308,11 @@ } , copyItemLink = function () { return config.f_host + canvasView.idata.href; } - , copyHash = function () { return canvasView.idata.hash; } + , copyHash = function () + { + var data = canvasView.idata; + return data.isCollection ? data.id : data.hash; + } , openAction = function () { diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js index 00cb176..15bf019 100644 --- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js +++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/SiteFile.js @@ -45,10 +45,25 @@ , __applyData = function (e) { - var finfo = JSON.parse(e).file, s, m, l - , content = this.stage.firstChild - , desc = this.stage.lastChild - , _hash = this.hash; + if( typeof( e ) == "string" ) + e = JSON.parse(e); + + var _stage = IDOMElement( this.stage ); + + var isAlbum = false; + // Check if this is an album + if( isAlbum = ( "files" in e ) ) + { + e.file = e.files[0]; + _stage.setAttribute( new DataKey( "collection", 1 ) ); + } + + var s, m, l; + + var finfo = e.file; + var content = this.stage.firstChild; + var desc = this.stage.lastChild; + var _hash = finfo.hash; switch ( finfo.type ) { @@ -56,34 +71,33 @@ this.stage.removeChild(content); // Default size is large - var _image = Dand.wrapna("img", new IKey("src", config.path.image.large + _hash + ".jpg")) - , _stage = IDOMElement(this.stage) - , keys = [ new IKey( "type", "radio" ), new IKey( "name", "size_grp" + Perf.uuid ) ] - , sid - , selectionChanged = function () + var _image = Dand.wrapna( "img", new IKey("src", config.path.image.large + _hash + ".jpg") ); + var keys = [ new IKey( "type", "radio" ), new IKey( "name", "size_grp" + Perf.uuid ) ]; + var sid; + var selectionChanged = function () { - _stage.setAttribute(new DataKey("size", this.size)); + _stage.setAttribute( new DataKey( "size", this.size ) ); //// Handles the size selection switch(this.size) { case "small": - _image.setAttribute("src", config.path.image.small + _hash + ".jpg"); + _image.setAttribute( "src", config.path.image.small + _hash + ".jpg" ); break; case "medium": - _image.setAttribute("src", config.path.image.medium + _hash + ".jpg"); + _image.setAttribute( "src", config.path.image.medium + _hash + ".jpg" ); break; case "large": - _image.setAttribute("src", config.path.image.large + _hash + ".jpg"); + _image.setAttribute( "src", config.path.image.large + _hash + ".jpg" ); break; } }; - this.stage.insertBefore(_image, desc); + this.stage.insertBefore( _image, desc ); - desc.removeChild(desc.firstChild); + desc.removeChild( desc.firstChild ); desc.appendChild( Dand.wrape([ - Dand.textNode("Size: ") + Dand.textNode( ( isAlbum ? "[Album] " : "" ) + "Size: ") , s = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) )) , Dand.wrapne("label", "small", new IKey("for", sid)) , m = Dand.wrapna("input", keys.concat( new IKey("id", sid = "size_" + Perf.uuid) )) @@ -112,7 +126,7 @@ , loadFailed = function (e) { } - , visualizer = function (submitted, override) + , visualizer = function ( submitted, override ) { var hash = override ? override.value : this.code.value @@ -128,9 +142,9 @@ , Dand.wrapc("v_description", "Site file (hash): " + hash) ] , [ - new DataKey("value", hash) - , new DataKey("size", "large") - , new IKey("style", "max-height: 150px;") + new DataKey( "value", hash ) + , new DataKey( "size", "large" ) + , new IKey( "style", "max-height: 150px;" ) ] ); @@ -162,6 +176,7 @@ stage = IDOMElement( stage ); // [html][/html] return "[sitefile" + + " collection=\"" + stage.getDAttribute( "collection" ) + "\"" + " size=\"" + stage.getDAttribute( "size" ) + "\"" + "]" + escapeStr( stage.getDAttribute( "value" ) ) + "[/sitefile]"; diff --git a/botanjs/src/Astro/Blog/Components/Album.css b/botanjs/src/Astro/Blog/Components/Album.css new file mode 100644 index 0000000..57c4c9f --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Album.css @@ -0,0 +1,4 @@ +.site_file[data-type="album"] > div { + display: inline-block; + margin: 0.5em; +} diff --git a/botanjs/src/Astro/Blog/Components/Album.js b/botanjs/src/Astro/Blog/Components/Album.js new file mode 100644 index 0000000..4753011 --- /dev/null +++ b/botanjs/src/Astro/Blog/Components/Album.js @@ -0,0 +1,92 @@ +(function(){ + var ns = __namespace( "Astro.Blog.Components" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.utils.IKey} */ + var IKey = __import( "System.utils.IKey" ); + /** @type {System.utils.DataKey} */ + var DataKey = __import( "System.utils.DataKey" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Dandelion.IDOMElement} */ + var IDOMElement = __import( "Dandelion.IDOMElement" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + /** @type {System.utils.Perf} **/ + var Perf = __import( "System.utils.Perf" ); + /** @type {Astro.Blog.Config} */ + var Conf = __import( "Astro.Blog.Config" ); + + /** @type {_AstConf_.SiteFile} */ + var config = null; + + var SiteFile = ns[ NS_INVOKE ]( "SiteFile" ); + + var Album = function ( id, hash ) + { + if( !config ) throw new Error( "config is not defined" ); + var stage = Dand.id( id, true ); + + var sf = new SiteFile( id, hash ); + if( sf.type != "album" ) return; + + var ostage = stage.element; + + var applyStructure = function( obj ) + { + // remove loading bubbles + while( ostage.hasChildNodes() ) ostage.removeChild( ostage.firstChild ); + + /** @type {_AstJson_.SiteFile} */ + var finfo = JSON.parse( obj ); + + var files = finfo.files; + var l = files.length; + for( var i = 0; i < l; i ++ ) + { + /** @type {_AstJson_.SiteFile} */ + var file = files[i]; + var uuid = Perf.uuid; + + ostage.appendChild( + Dand.wrapna( "div", [ + new IKey( "id", uuid ) + , new DataKey( "size", "medium" ) + ] ) + ); + + Cycle.next( function() + { + new SiteFile( this.id, this.hash ); + }.bind({ id: uuid, hash: file.hash }) ); + } + + console.log( finfo ); + }; + + var loadFailed = function( obj ) + { + console.log( obj ); + }; + + sf.loadInfo( applyStructure, loadFailed ); + }; + + var init = function() + { + config = Conf.get( "SiteFile" ); + if( config ) + { + for( var i in config.files ) + { + var f = config.files[i]; + new Album( f[0], f[1] ); + } + } + }; + + Bootstrap.regInit( init ); + + ns[ NS_EXPORT ]( EX_CLASS, "Album", Album ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/Entry/Block.css b/botanjs/src/Astro/Blog/Components/Entry/Block.css index 588da7c..3232879 100644 --- a/botanjs/src/Astro/Blog/Components/Entry/Block.css +++ b/botanjs/src/Astro/Blog/Components/Entry/Block.css @@ -1,4 +1,4 @@ -.bk_block { +.block-entries .block { float: left; width: 225px; @@ -7,33 +7,38 @@ margin: 1em; position: relative; - overflow: hidden; color: #666; - background-color: white; - border: 1px solid #D4D7C9; + border: 2px solid transparent; display: block; } -.bk_block:hover { - text-decoration: none; +.block-entries .block:hover { + border-width: 2px; + border-color: purple; } -.bk_SlideWrapper { +.block-entries .slide-wrapper { position: absolute; overflow: hidden; - top: 0.5em; width: 100%; height: 100%; + + border: 1px solid #D4D7C9; + margin: -1px; } -.bk_date { +.block-entries .slide-wrapper:hover { + border-color: purple; +} + +.block-entries .date { font-size: 0.8em; text-align: right; } -.bk_title { +.block-entries .title { font-size: 1.2em; max-height: 2.4em; overflow: hidden; @@ -41,17 +46,17 @@ color: #444; } -.bk_content { +.block-entries .content { text-overflow: ellipsis; overflow: hidden; } -.bk_author { +.block-entries .author { color: crimson; text-align: right; } -.bk_cCount { +.block-entries .c-count { position: absolute; bottom: 1em; left: 0.5em; @@ -62,7 +67,7 @@ } -.bk_blockSlide { +.block-entries .slide { position: absolute; width: 100%; height: 150%; @@ -70,7 +75,7 @@ top: 0; } -.bk_blockSlide:after { +.block-entries .slide:after, .block-entries[on] .slide { content: attr(data-content); position: absolute; @@ -82,9 +87,6 @@ padding: 0 0.5em; - font-size: 0.8em; - font-family: custom-serif; - color: #EEE; background: purple; @@ -112,16 +114,16 @@ transition-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); /* easeOutCubic */ } -.bk_blockSlide:hover:after { +.block-entries .slide:hover:after, .slide[on]:after { top: 62.5%; padding: 0.5em; } -.bk_blockSlide:hover { +.block-entries .slide:hover, .slide[on] { top: -50%; } -.bk_blockFront { +.block-entries .front { position: absolute; background: white; @@ -129,19 +131,30 @@ height: 100%; } -.bk_blockWrapper { +.block-entries .block-wrapper { position: relative; - padding: 0 0.5em; + background-image: repeating-linear-gradient( + 135deg + , transparent, transparent 1px + , rgba( 85, 85, 85, .1 ) 1px + , rgba( 85, 85, 85, .1 ) 30px + ); + background-color: black; } -.bk_banner { +.block-entries .block-info { + padding: 0.5em; + background: white; +} + +.block-entries .banner { width: 50%; padding: 50%; - background-image: url(http://file.astropenguin.net/blog/layout-images/featured.png); background-position: center; background-repeat: no-repeat; - background-color: white; + + border-bottom: 1px solid #D4D7C9; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; diff --git a/botanjs/src/Astro/Blog/Components/Entry/Block.js b/botanjs/src/Astro/Blog/Components/Entry/Block.js index e406e74..8df6cdd 100644 --- a/botanjs/src/Astro/Blog/Components/Entry/Block.js +++ b/botanjs/src/Astro/Blog/Components/Entry/Block.js @@ -1 +1,90 @@ -// __namespace( "Astro.Blog.Components.Entry.Block" ); +(function(){ + var ns = __namespace( "Astro.Blog.Components.Entry" ); + + /** @type {System.Cycle} */ + var Cycle = __import( "System.Cycle" ); + /** @type {System.utils.Perf} */ + var Perf = __import( "System.utils.Perf" ); + /** @type {Dandelion} */ + var Dand = __import( "Dandelion" ); + /** @type {Astro.Bootstrap} */ + var Bootstrap = __import( "Astro.Bootstrap" ); + + /** @type {Astro.Blog.Config} */ + var Conf = __import( "Astro.Blog.Config" ); + /** @type {Astro.Blog.Components.SiteFile} */ + var SiteFile = __import( "Astro.Blog.Components.SiteFile" ); + + /** @type {_AstConf_.SiteFile} */ + var config = null; + + var Block = function ( element ) + { + if( !config ) throw new Error( "Config is not defined" ); + var slide = Dand.glass( "slide", false, element )[0]; + var delayCont = function( firstTime ) + { + Cycle.delay( + function() + { + slide.getAttribute( "on" ) + ? slide.removeAttribute( "on" ) + : slide.setAttribute( "on", 1 ) + ; + delayCont( false ); + } + , firstTime + ? ( 500 + Math.random()*4500 ) + : ( 5500 + Math.random()*4500 ) + ); + }; + + delayCont( true ); + + var banner = Dand.glass( "banner", false, element )[0]; + var bId = banner.getAttribute( "id" ); + + var placeBackground = function( obj ) + { + /** @type {_AstJson_.SiteFile} */ + var finfo = JSON.parse( obj ); + + /** @type {_AstJson_.SiteFile} */ + var file = finfo.files[0]; + + var path = config.path.image.medium + file.hash + ".jpg"; + banner.style.backgroundImage = "url(" + path + ")"; + }; + + var placeError = function( obj ) + { + throw new Error( obj ); + }; + + for( var i in config.files ) + { + var f = config.files[i]; + var id = f[0]; + if( id == bId ) + { + new SiteFile( id, f[1] ).loadInfo( placeBackground, placeError ); + } + } + }; + + var init = function() + { + config = Conf.get( "SiteFile" ); + + var stage = Dand.glass( "block-entries" )[0]; + var everyEntries = Dand.glass( "block", false, stage ); + for( var i = 0; i < everyEntries.length; i ++ ) + { + new Block( everyEntries[ i ] ); + } + }; + + Bootstrap.regInit( init ); + + ns[ NS_EXPORT ]( EX_CLASS, "Block", Block ); +})(); diff --git a/botanjs/src/Astro/Blog/Components/SiteFile.js b/botanjs/src/Astro/Blog/Components/SiteFile.js index ad2a7bd..f1b9a32 100644 --- a/botanjs/src/Astro/Blog/Components/SiteFile.js +++ b/botanjs/src/Astro/Blog/Components/SiteFile.js @@ -1,7 +1,7 @@ (function(){ var ns = __namespace( "Astro.Blog.Components" ); - /** @type {System.utils.EventKey} */ + /** @type {System.utils.IKey} */ var IKey = __import( "System.utils.IKey" ); /** @type {Dandelion} */ var Dand = __import( "Dandelion" ); @@ -22,110 +22,121 @@ { if( !config ) throw new Error( "config is not defined" ); // TODO: Make a trigger for downloading from server - var stage = Dand.id( id ) + var stage = Dand.id( id ); + this.id = id; + this.hash = hash; + this.type = IDOMElement( stage ).getDAttribute( "type" ); - , applyStructure = function( obj ) - { - // remove loading bubbles - while( stage.hasChildNodes() ) stage.removeChild(stage.firstChild); + if(!( this.type == "default" || this.type == null )) return this; + if( stage.getAttribute( "noauto" ) != null ) return this; - /** @type {_AstJson_.SiteFile} */ - var finfo = JSON.parse( obj ).file; + var applyStructure = function( obj ) + { + // remove loading bubbles + while( stage.hasChildNodes() ) stage.removeChild(stage.firstChild); - switch( finfo.type ) { + /** @type {_AstJson_.SiteFile} */ + var finfo = JSON.parse( obj ).file; - case "image": - var node = Dand.wrap('img'); - var k = new IKey( "src", null ); + switch( finfo.type ) { - switch( IDOMElement(stage).getDAttribute('size') ) - { - case "small": - k.keyValue = config.path.image.small + hash + '.jpg'; - break; - case "medium": - k.keyValue = config.path.image.medium + hash + '.jpg'; - break; - default: // large - k.keyValue = config.path.image.large + hash + '.jpg'; - } - IDOMElement( node ).setAttribute( k ); + case "image": + var node = Dand.wrap('img'); + var k = new IKey( "src", null ); - stage.appendChild(Dand.wrapne( - 'a', node + switch( IDOMElement(stage).getDAttribute('size') ) + { + case "small": + k.keyValue = config.path.image.small + hash + '.jpg'; + break; + case "medium": + k.keyValue = config.path.image.medium + hash + '.jpg'; + break; + default: // large + k.keyValue = config.path.image.large + hash + '.jpg'; + } + IDOMElement( node ).setAttribute( k ); + + stage.appendChild(Dand.wrapne( + 'a', node + , [ + new IKey( 'href', config.f_host + finfo.src_location ) + , new IKey( 'title', finfo.name ) + , new IKey( 'target', '_blank' ) + ] + )); + + break; + + case "audio": + // TODO + break; + + default: + // create a form to post hash string to php + var hash_field = Dand.wrapna( + 'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'hash' ) ] + ) + , name_field = Dand.wrapna( + 'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'name' ) ] + ) + , link = Dand.wrapne( + 'a', 'download', new IKey( 'href', config.path.download + finfo.name ) + ) + + , form = Dand.wrap( + 'form', null, 'sf_regular' + , [ name_field, hash_field ] , [ - new IKey( 'href', config.f_host + finfo.src_location ) - , new IKey( 'title', finfo.name ) - , new IKey( 'target', '_blank' ) + new IKey('target', '_blank') + , new IKey('action', config.path.download + finfo.name) + , new IKey('method', 'POST') ] - )); + ) + ; - break; + hash_field.value = hash; + name_field.value = finfo.name; - case "audio": - // TODO - break; + IDOMElement(link).addEventListener( + 'Click' + , function(e) { + form.submit(); + e.preventDefault(); + return false; + } + ); - default: - // create a form to post hash string to php - var hash_field = Dand.wrapna( - 'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'hash' ) ] - ) - , name_field = Dand.wrapna( - 'input', [ new IKey( 'type', 'hidden' ), new IKey( 'name', 'name' ) ] - ) - , link = Dand.wrapne( - 'a', 'download', new IKey( 'href', config.path.download + finfo.name ) - ) + // file name + form.appendChild( Dand.wrapne( 'span', 'File: ' + finfo.name) ); - , form = Dand.wrap( - 'form', null, 'sf_regular' - , [ name_field, hash_field ] - , [ - new IKey('target', '_blank') - , new IKey('action', config.path.download + finfo.name) - , new IKey('method', 'POST') - ] - ) - ; + // download, submit button + form.appendChild( Dand.wrapne( 'sup', [ Dand.textNode(" ["), link, Dand.textNode("]") ] ) ); - hash_field.value = hash; - name_field.value = finfo.name; - - IDOMElement(link).addEventListener( - 'Click' - , function(e) { - form.submit(); - e.preventDefault(); - return false; - } - ); - - // file name - form.appendChild( Dand.wrapne( 'span', 'File: ' + finfo.name) ); - - // download, submit button - form.appendChild( Dand.wrapne( 'sup', [ Dand.textNode(" ["), link, Dand.textNode("]") ] ) ); - - // hash - form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'MD5: ' + hash ) ) ); - // date - form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'Date: ' + getSMStamp( new Date( finfo.date_created ) ) ) ) ); + // hash + form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'MD5: ' + hash ) ) ); + // date + form.appendChild( Dand.wrapne( 'sup', Dand.wrape( 'Date: ' + getSMStamp( new Date( finfo.date_created ) ) ) ) ); - stage.appendChild(form); - - } + stage.appendChild(form); } - , loadFailed = function( obj ) - { - while( stage.hasChildNodes() ) stage.removeChild( stage.firstChild ); - stage.appendChild( Dand.wrapc( "sf_failed", Dand.textNode( "Error: Failed to get resources info" ) ) ); - } - ; - getData( config.path.info + hash, applyStructure, loadFailed ); + }; + + var loadFailed = function( obj ) + { + while( stage.hasChildNodes() ) stage.removeChild( stage.firstChild ); + stage.appendChild( Dand.wrapc( "sf_failed", Dand.textNode( "Error: Failed to get resources info" ) ) ); + }; + + this.loadInfo( applyStructure, loadFailed ); + }; + + SiteFile.prototype.loadInfo = function( success, failed ) + { + getData( config.path.info + this.hash, success, failed ); }; var init = function() diff --git a/botanjs/src/externs/Astro.Blog.Components.SiteFile.js b/botanjs/src/externs/Astro.Blog.Components.SiteFile.js new file mode 100644 index 0000000..b3123e9 --- /dev/null +++ b/botanjs/src/externs/Astro.Blog.Components.SiteFile.js @@ -0,0 +1,12 @@ +/** @constructor */ +Astro.Blog.Components.SiteFile = function() {}; + +/** @type {Function} */ +Astro.Blog.Components.SiteFile.loadInfo; + +/** @type {String} */ +Astro.Blog.Components.SiteFile.hash; +/** @type {String} */ +Astro.Blog.Components.SiteFile.id; +/** @type {String} */ +Astro.Blog.Components.SiteFile.type;