From b0d9895e5e7fed8b8e9391586883019dce2bdc28 Mon Sep 17 00:00:00 2001 From: Rokt33r Date: Mon, 13 Jul 2015 13:05:54 +0900 Subject: [PATCH] add Article detail --- browser/main/Actions/fetchPlanet.js | 5 + browser/main/Actions/fetchSnippets.js | 0 browser/main/Actions/snippetUpdate.js | 6 - browser/main/Actions/updateSnippet.js | 6 + browser/main/Containers/LoginContainer.jsx | 3 +- browser/main/Containers/PlanetContainer.jsx | 204 +++++++++++------- browser/main/Containers/RegisterContainer.jsx | 2 +- browser/main/Containers/SnippetContainer.jsx | 169 --------------- browser/main/Containers/UserContainer.jsx | 37 +--- browser/main/Mixins/OnlyGuest.js | 2 +- browser/main/Stores/PlanetStore.js | 37 ++++ browser/main/index.jsx | 9 +- .../styles/main/components/SideNavigator.styl | 22 -- .../main/containers/PlanetContainer.styl | 179 +++++++++++++++ .../main/containers/SnippetContainer.styl | 62 ------ browser/styles/main/index.styl | 101 --------- 16 files changed, 375 insertions(+), 469 deletions(-) create mode 100644 browser/main/Actions/fetchPlanet.js create mode 100644 browser/main/Actions/fetchSnippets.js delete mode 100644 browser/main/Actions/snippetUpdate.js create mode 100644 browser/main/Actions/updateSnippet.js delete mode 100644 browser/main/Containers/SnippetContainer.jsx create mode 100644 browser/main/Stores/PlanetStore.js create mode 100644 browser/styles/main/containers/PlanetContainer.styl delete mode 100644 browser/styles/main/containers/SnippetContainer.styl diff --git a/browser/main/Actions/fetchPlanet.js b/browser/main/Actions/fetchPlanet.js new file mode 100644 index 00000000..19a28ab3 --- /dev/null +++ b/browser/main/Actions/fetchPlanet.js @@ -0,0 +1,5 @@ +var Reflux = require('reflux') + +var fetchPlanet = Reflux.createAction() + +module.exports = fetchPlanet diff --git a/browser/main/Actions/fetchSnippets.js b/browser/main/Actions/fetchSnippets.js new file mode 100644 index 00000000..e69de29b diff --git a/browser/main/Actions/snippetUpdate.js b/browser/main/Actions/snippetUpdate.js deleted file mode 100644 index 138dc565..00000000 --- a/browser/main/Actions/snippetUpdate.js +++ /dev/null @@ -1,6 +0,0 @@ -var Reflux = require('reflux') - -// Creating an Action -var snippetUpdate = Reflux.createAction() - -module.exports = snippetUpdate diff --git a/browser/main/Actions/updateSnippet.js b/browser/main/Actions/updateSnippet.js new file mode 100644 index 00000000..e3589a4e --- /dev/null +++ b/browser/main/Actions/updateSnippet.js @@ -0,0 +1,6 @@ +var Reflux = require('reflux') + +// Creating an Action +var updateSnippet = Reflux.createAction() + +module.exports = updateSnippet diff --git a/browser/main/Containers/LoginContainer.jsx b/browser/main/Containers/LoginContainer.jsx index 5d09963b..17341786 100644 --- a/browser/main/Containers/LoginContainer.jsx +++ b/browser/main/Containers/LoginContainer.jsx @@ -1,4 +1,3 @@ -/* global localStorage */ var React = require('react/addons') var ReactRouter = require('react-router') var Link = ReactRouter.Link @@ -35,7 +34,7 @@ module.exports = React.createClass({ this.transitionTo('user', {userName: user.name}) return } - this.transitionTo('dashboard', {userName: user.name, planetName: planet.name}) + this.transitionTo('planetHome', {userName: user.name, planetName: planet.name}) }, render: function () { return ( diff --git a/browser/main/Containers/PlanetContainer.jsx b/browser/main/Containers/PlanetContainer.jsx index 81b40ee4..b428ba33 100644 --- a/browser/main/Containers/PlanetContainer.jsx +++ b/browser/main/Containers/PlanetContainer.jsx @@ -1,33 +1,14 @@ var React = require('react/addons') var RouteHandler = require('react-router').RouteHandler var ReactRouter = require('react-router') -var Link = ReactRouter.Link var ModalBase = require('../Components/ModalBase') var LaunchModal = require('../Components/LaunchModal') +var CodeViewer = require('../Components/CodeViewer') -var currentUser = { - name: 'testcat', - email: 'testcat@example.com', - profileName: 'Test Cat' -} +var AuthStore = require('../Stores/AuthStore') +var PlanetStore = require('../Stores/PlanetStore') -var userPlanets = [ - { - id: 1, - name: 'myplanet', - profileName: 'TestCat' - }, - { - id: 2, - name: 'group1', - profileName: 'Some Group#1' - }, - { - id: 3, - name: 'group2', - profileName: 'Some Group#1' - } -] +var fetchPlanet = require('../Actions/fetchPlanet') var PlanetHeader = React.createClass({ propTypes: { @@ -76,24 +57,7 @@ var PlanetHeader = React.createClass({ ) } }) - -var PlanetMain = React.createClass({ - propTypes: { - currentPlanet: React.PropTypes.object, - currentUser: React.PropTypes.object - }, - render: function () { - return ( -
- - - -
- ) - } -}) - -var SideNavigator = React.createClass({ +var PlanetNavigator = React.createClass({ propTypes: { currentPlanet: React.PropTypes.shape({ name: React.PropTypes.string @@ -119,11 +83,8 @@ var SideNavigator = React.createClass({ this.setState({isLaunchModalOpen: false}) }, render: function () { - var currentPlanetName = this.props.currentPlanet.name - var currentUserName = this.props.currentUser.name - return ( -
+
@@ -131,60 +92,159 @@ var SideNavigator = React.createClass({
) } }) -var PlanetBody = React.createClass({ +var PlanetArticleList = React.createClass({ + mixins: [ReactRouter.Navigation, ReactRouter.State], + propTypes: { + planet: React.PropTypes.shape({ + Snippets: React.PropTypes.array, + Blueprints: React.PropTypes.array + }) + }, render: function () { + var articles = this.props.planet.Snippets.map(function (snippet) { + var tags = snippet.Tags.map(function (tag) { + return ( + #{tag.name} + ) + }) + var params = this.getParams() + + var isActive = parseInt(params.localId, 10) === snippet.localId + + var handleClick = function () { + this.transitionTo('snippets', { + userName: params.userName, + planetName: params.planetName, + localId: snippet.localId + }) + }.bind(this) + + return ( +
  • +
    {snippet.callSign}
    +
    {snippet.description}
    +
    {snippet.updatedAt}
    +
    {tags}
    +
  • + ) + }.bind(this)) + return ( -
    - +
    +
      + {articles} +
    +
    + ) + } +}) + +var PlanetArticleDetail = React.createClass({ + propTypes: { + snippet: React.PropTypes.object + }, + render: function () { + var snippet = this.props.snippet + + var tags = snippet.Tags.map(function (tag) { + return ( + #{tag.name} + ) + }) + + return ( +
    +
    + {snippet.callSign} {snippet.updatedAt} + + + + +
    +
    +
    +
    {snippet.description}
    +
    {tags}
    +
    +
    + +
    +
    ) } }) module.exports = React.createClass({ - mixins: [ReactRouter.Navigation], + mixins: [ReactRouter.Navigation, ReactRouter.State], propTypes: { params: React.PropTypes.object, planetName: React.PropTypes.string }, - render: function () { - var currentPlanetName = this.props.params.planetName - var currentPlanet = null - userPlanets.some(function (planet) { - if (planet.name === currentPlanetName) { - currentPlanet = planet - return true + getInitialState: function () { + return { + currentPlanet: null + } + }, + componentDidMount: function () { + this.unsubscribe = PlanetStore.listen(this.onFetched) + + fetchPlanet(this.props.params.userName + '/' + this.props.params.planetName) + }, + componentWillUnmount: function () { + this.unsubscribe() + }, + onFetched: function (planet) { + this.setState({currentPlanet: planet}, function () { + if (planet.Snippets.length > 0) { + this.transitionTo('snippets', { + userName: this.props.params.userName, + planetName: this.props.params.planetName, + localId: planet.Snippets[0].localId}) } - return false }) - if (currentPlanet == null) { - var redirectTo = userPlanets[0].name - this.transitionTo('planet', {planetName: redirectTo}) - return ( -
    - Redirecting... -
    - ) + }, + render: function () { + var user = AuthStore.getUser() + if (user == null) return (
    ) + if (this.state.currentPlanet == null) return (
    ) + + var content = (
    No selected
    ) + if (this.isActive('snippets')) { + var localId = parseInt(this.props.params.localId, 10) + + this.state.currentPlanet.Snippets.some(function (_snippet) { + if (localId === _snippet.localId) { + content = ( + + ) + return true + } + return false + }) } return (
    - + + + + {content}
    ) } diff --git a/browser/main/Containers/RegisterContainer.jsx b/browser/main/Containers/RegisterContainer.jsx index b1898cc1..17db70f5 100644 --- a/browser/main/Containers/RegisterContainer.jsx +++ b/browser/main/Containers/RegisterContainer.jsx @@ -39,7 +39,7 @@ module.exports = React.createClass({ this.transitionTo('user', {userName: user.name}) return } - this.transitionTo('dashboard', {userName: user.name, planetName: planet.name}) + this.transitionTo('planetHome', {userName: user.name, planetName: planet.name}) }, render: function () { return ( diff --git a/browser/main/Containers/SnippetContainer.jsx b/browser/main/Containers/SnippetContainer.jsx deleted file mode 100644 index 14f6dc51..00000000 --- a/browser/main/Containers/SnippetContainer.jsx +++ /dev/null @@ -1,169 +0,0 @@ -var React = require('react/addons') -var Snippet = require('../Services/Snippet') -var CodeViewer = require('../Components/CodeViewer') - -var SnippetList = React.createClass({ - propTypes: { - snippets: React.PropTypes.array, - selectSnippet: React.PropTypes.func, - currentSnippet: React.PropTypes.object - }, - itemClickHandlerFactory: function (snippet) { - return function () { - this.props.selectSnippet(snippet) - }.bind(this) - }, - render: function () { - var snippets = this.props.snippets.map(function (snippet) { - var tags = snippet.Tags.map(function (tag) { - return ( - #{tag.name} - ) - }) - return ( -
  • -
    {snippet.callSign}
    -
    {snippet.description}
    -
    {snippet.updatedAt}
    -
    {tags}
    -
  • - ) - }.bind(this)) - - return ( -
    -
      - {snippets} -
    -
    - ) - } -}) - -var SnippetViewer = React.createClass({ - propTypes: { - snippet: React.PropTypes.object - }, - render: function () { - var snippet = this.props.snippet - var content - if (snippet != null) { - var tags = snippet.Tags.map(function (tag) { - return ( - #{tag.name} - ) - }) - content = ( -
    -
    - {snippet.callSign} {snippet.updatedAt} - - - - -
    -
    -
    -
    {snippet.description}
    -
    {tags}
    -
    -
    - -
    -
    -
    - ) - } else { - content = ( -
    - Not selected -
    - ) - } - return content - } -}) - -var SnippetContainer = React.createClass({ - propTypes: { - params: React.PropTypes.shape({ - planetName: React.PropTypes.string - }) - }, - getInitialState: function () { - return { - snippets: [], - curentSnippet: {} - } - }, - componentDidMount: function () { - Snippet.getByPlanet(this.props.params.planetName) - .then(function (snippets) { - this.setSnippets(snippets, snippets.length > 0 ? snippets[0] : null) - }.bind(this)) - }, - setSnippets: function (snippets, currentSnippet) { - this.setState({snippets: snippets, currentSnippet: currentSnippet}) - }, - selectSnippet: function (snippet) { - this.setState({currentSnippet: snippet}) - }, - updateSnippet: function (snippet) { - var snippets = this.state.snippets.map(function (_snippet) { - if (snippet.id === _snippet.id) { - return snippet - } - return _snippet - }) - var currentSnippet = this.state.currentSnippet.id === snippet.id ? snippet : this.state.currentSnippet - - this.setState({snippets: snippets, currentSnippet: currentSnippet}) - }, - destroySnippet: function (snippet) { - var snippets = this.state.snippets - var currentSnippet = this.state.currentSnippet - if (currentSnippet.id === snippet.id) { - var index - snippets.some(function (_snippet, _index) { - if (snippet.id === _snippet.id) { - index = _index - return true - } - return false - }) - - if (index == null) { - index = 0 - } else if (index > snippet.length - 1) { - index-- - } else { - index++ - } - - if (snippets.length > 0) { - currentSnippet = snippets[index] - } else { - currentSnippet = {} - } - } - - snippets = snippets.filter(function (_snippet, index) { - if (snippet.id === _snippet.id) { - return false - } - return true - }) - - this.setState({snippets: snippets, currentSnippet: currentSnippet}) - }, - render: function () { - return ( -
    - - -
    - ) - } -}) - -module.exports = SnippetContainer diff --git a/browser/main/Containers/UserContainer.jsx b/browser/main/Containers/UserContainer.jsx index 828bf2ff..dfa75d88 100644 --- a/browser/main/Containers/UserContainer.jsx +++ b/browser/main/Containers/UserContainer.jsx @@ -3,30 +3,7 @@ var ReactRouter = require('react-router') var Link = ReactRouter.Link var RouteHandler = ReactRouter.RouteHandler -// Dummy -var currentUser = { - name: 'testcat', - email: 'testcat@example.com', - profileName: 'Test Cat' -} - -var userPlanets = [ - { - id: 1, - name: 'testcat', - profileName: 'TestCat' - }, - { - id: 2, - name: 'group1', - profileName: 'Some Group#1' - }, - { - id: 3, - name: 'group2', - profileName: 'Some Group#1' - } -] +var AuthStore = require('../Stores/AuthStore') var UserNavigator = React.createClass({ propTypes: { @@ -34,10 +11,10 @@ var UserNavigator = React.createClass({ currentUser: React.PropTypes.object }, render: function () { - var planets = userPlanets.map(function (planet, index) { + var planets = this.props.currentUser.Planets.map(function (planet, index) { return (
  • - {planet.profileName[0]} + {planet.name[0]}
    ⌘{index + 1}
  • ) @@ -65,10 +42,16 @@ var UserNavigator = React.createClass({ module.exports = React.createClass({ mixins: [React.addons.LinkedStateMixin, ReactRouter.Navigation], + propTypes: { + params: React.PropTypes.shape({ + planetName: React.PropTypes.string + }) + }, render: function () { var currentPlanetName = this.props.params.planetName + var currentUser = AuthStore.getUser() var currentPlanet = null - userPlanets.some(function (planet) { + currentUser.Planets.some(function (planet) { if (planet.name === currentPlanetName) { currentPlanet = planet return true diff --git a/browser/main/Mixins/OnlyGuest.js b/browser/main/Mixins/OnlyGuest.js index 0b86e2e8..c4103b8b 100644 --- a/browser/main/Mixins/OnlyGuest.js +++ b/browser/main/Mixins/OnlyGuest.js @@ -12,7 +12,7 @@ var OnlyGuest = { this.transitionTo('user', {userName: user.name}) return } - this.transitionTo('dashboard', {userName: user.name, planetName: planet.name}) + this.transitionTo('planetHome', {userName: user.name, planetName: planet.name}) } } } diff --git a/browser/main/Stores/PlanetStore.js b/browser/main/Stores/PlanetStore.js new file mode 100644 index 00000000..d75c85e6 --- /dev/null +++ b/browser/main/Stores/PlanetStore.js @@ -0,0 +1,37 @@ +var Reflux = require('reflux') +var request = require('superagent') + +var fetchPlanet = require('../Actions/fetchPlanet') + +var updateSnippet = require('../Actions/updateSnippet') +var fetchSnippets = require('../Actions/fetchSnippets') + +var PlanetStore = Reflux.createStore({ + init: function () { + // this.listenTo(updateSnippet, this.updateSnippet) + // this.listenTo(fetchSnippets, this.fetchSnippets) + this.listenTo(fetchPlanet, this.fetchPlanet) + }, + // planetName = user.name/planet.name + fetchPlanet: function (planetName) { + request + .get('http://localhost:8000/' + planetName) + .send() + .end(function (err, res) { + if (err) { + console.error(err) + this.trigger(null) + return + } + + var planet = res.body + + this.trigger(planet) + }.bind(this)) + }, + updateSnippet: function (input) { + + } +}) + +module.exports = PlanetStore diff --git a/browser/main/index.jsx b/browser/main/index.jsx index 9425e191..dca93960 100644 --- a/browser/main/index.jsx +++ b/browser/main/index.jsx @@ -15,9 +15,6 @@ var RegisterContainer = require('./Containers/RegisterContainer.jsx') var UserContainer = require('./Containers/UserContainer.jsx') var UserSettingContainer = require('./Containers/UserSettingContainer.jsx') var PlanetContainer = require('./Containers/PlanetContainer.jsx') -var DashboardContainer = require('./Containers/DashboardContainer.jsx') -var SnippetContainer = require('./Containers/SnippetContainer.jsx') -var BlueprintContainer = require('./Containers/BlueprintContainer.jsx') var routes = ( @@ -27,9 +24,9 @@ var routes = ( - - - + + + diff --git a/browser/styles/main/components/SideNavigator.styl b/browser/styles/main/components/SideNavigator.styl index 5f782f12..e69de29b 100644 --- a/browser/styles/main/components/SideNavigator.styl +++ b/browser/styles/main/components/SideNavigator.styl @@ -1,22 +0,0 @@ -.SideNavigator - absolute bottom left - top 65px - width 200px - border-right solid 1px highlightenBorderColor - padding 10px - box-sizing border-box - nav - a - display block - box-sizing border-box - padding 15px 15px - margin 10px 0 - border-radius 10px - text-decoration none - background-color transparent - color textColor - transition 0.1s - &:hover, &.hover - background-color hoverBackgroundColor - &:active, &.active - color brandColor diff --git a/browser/styles/main/containers/PlanetContainer.styl b/browser/styles/main/containers/PlanetContainer.styl new file mode 100644 index 00000000..6eb7a997 --- /dev/null +++ b/browser/styles/main/containers/PlanetContainer.styl @@ -0,0 +1,179 @@ + +.PlanetContainer + absolute top bottom right + left 50px + +.PlanetHeader + absolute left right top + overflow-y hidden + height 65px + background-color white + border-bottom solid 1px borderColor + box-sizing border-box + padding 5px 15px + clearfix() + .planetName + line-height 30px + font-size 2em + color brandColor + line-height 55px + padding 0 20px + .menuBtn + display inline-block + position relative + top -5px + font-size 0.8em + color lightButtonColor + border solid 1px lightButtonColor + box-sizing border-box + circle() + background-image none + background-color transparent + width 30px + height 30px + text-align center + cursor pointer + transition 0.1s + transform scale(0.8) + &:focus, &.focus + outline none + &:hover, &.hover, &:focus, &.focus + border-color darken(lightButtonColor, 25%) + color darken(lightButtonColor, 25%) + &:active, &.active + border-color darken(brandBorderColor, 10%) + background-color brandColor + color white + .searchInput + display inline-block + position relative + top -3px + margin-left 15px + input + padding-left 32px + .fa + position absolute + top 7px + left 10px + .downloadBtn + position relative + float right + top 5px + padding 7px 25px + box-sizing border-box + line-height 30px + .dropDown + z-index 500 + position fixed + background white + width 200px + border solid 1px borderColor + box-sizing border-box + margin-top -5px + margin-left 125px + box-shadow popupShadow + &.hide + visibility hidden + a + color textColor + display block + width 100% + padding 15px + box-sizing border-box + border-bottom solid 1px borderColor + text-decoration none + &:hover, &.hover + background-color hoverBackgroundColor + &:focus, &.focus + color black + &:active, &.active + color brandColor + &:last-child + border-bottom none + +.PlanetNavigator + absolute bottom left + top 65px + width 200px + border-right solid 1px highlightenBorderColor + padding 10px + box-sizing border-box + nav + a + display block + box-sizing border-box + padding 15px 15px + margin 10px 0 + border-radius 10px + text-decoration none + background-color transparent + color textColor + transition 0.1s + &:hover, &.hover + background-color hoverBackgroundColor + &:active, &.active + color brandColor + +.PlanetArticleList + absolute bottom right + left 200px + top 65px + .tags + a + margin 0 2px + width 250px + border-right solid 1px highlightenBorderColor + + &>ul + absolute top bottom left right + overflow-y auto + li + border-bottom solid 1px borderColor + padding 10px + cursor pointer + .callSign + margin-bottom 5px + font-weight 600 + .description + margin-bottom 5px + .updatedAt + margin-bottom 5px + color lighten(textColor, 25%) + font-size 0.8em + &:hover, &.hover + background-color hoverBackgroundColor + &:active, &.active + background-color white + &:active, &.active + border solid 2px brandBorderColor + padding 9px 9px 8px + +.PlanetArticleDetail + absolute right bottom + top 65px + left 450px + .viewer-header + height 44px + line-height 44px + padding 0 15px + border-bottom solid 1px borderColor + box-sizing border-box + small + font-size 0.5em + .control-group + float right + button + margin 0 2px + .viewer-body + absolute bottom right + left 1px + top 44px + .viewer-detail + border-bottom solid 1px borderColor + padding 10px + .description + margin-bottom 15px + .content + padding 5px 0 + .ace_editor + height 500px diff --git a/browser/styles/main/containers/SnippetContainer.styl b/browser/styles/main/containers/SnippetContainer.styl deleted file mode 100644 index 08891aa3..00000000 --- a/browser/styles/main/containers/SnippetContainer.styl +++ /dev/null @@ -1,62 +0,0 @@ -.SnippetContainer - fullsize() - .tags - a - margin 0 2px - .SnippetList - absolute top bottom left - width 250px - border-right solid 1px highlightenBorderColor - - &>ul - absolute top bottom left right - overflow-y auto - li - border-bottom solid 1px borderColor - padding 10px - cursor pointer - .callSign - margin-bottom 5px - font-weight 600 - .description - margin-bottom 5px - .updatedAt - margin-bottom 5px - color lighten(textColor, 25%) - font-size 0.8em - &:hover, &.hover - background-color hoverBackgroundColor - &:active, &.active - background-color white - &:active, &.active - border solid 2px brandBorderColor - padding 9px 9px 8px - - .SnippetViewer - absolute top bottom right - left 250px - .viewer-header - height 44px - line-height 44px - padding 0 15px - border-bottom solid 1px borderColor - box-sizing border-box - small - font-size 0.5em - .control-group - float right - button - margin 0 2px - .viewer-body - absolute bottom right - left 1px - top 44px - .viewer-detail - border-bottom solid 1px borderColor - padding 10px - .description - margin-bottom 15px - .content - padding 5px 0 - .ace_editor - height 500px diff --git a/browser/styles/main/index.styl b/browser/styles/main/index.styl index d2009801..9449be81 100644 --- a/browser/styles/main/index.styl +++ b/browser/styles/main/index.styl @@ -156,104 +156,3 @@ textarea.block-input border-color darken(brandBorderColor, 10%) background-color brandColor color white - -.PlanetContainer - absolute top bottom right - left 50px - -.PlanetMain - fullsize() - -.PlanetHeader - absolute left right top - overflow-y hidden - height 65px - background-color white - border-bottom solid 1px borderColor - box-sizing border-box - padding 5px 15px - clearfix() - .planetName - line-height 30px - font-size 2em - color brandColor - line-height 55px - padding 0 20px - .menuBtn - display inline-block - position relative - top -5px - font-size 0.8em - color lightButtonColor - border solid 1px lightButtonColor - box-sizing border-box - circle() - background-image none - background-color transparent - width 30px - height 30px - text-align center - cursor pointer - transition 0.1s - transform scale(0.8) - &:focus, &.focus - outline none - &:hover, &.hover, &:focus, &.focus - border-color darken(lightButtonColor, 25%) - color darken(lightButtonColor, 25%) - &:active, &.active - border-color darken(brandBorderColor, 10%) - background-color brandColor - color white - .searchInput - display inline-block - position relative - top -3px - margin-left 15px - input - padding-left 32px - .fa - position absolute - top 7px - left 10px - .downloadBtn - position relative - float right - top 5px - padding 7px 25px - box-sizing border-box - line-height 30px - .dropDown - z-index 500 - position fixed - background white - width 200px - border solid 1px borderColor - box-sizing border-box - margin-top -5px - margin-left 125px - box-shadow popupShadow - &.hide - visibility hidden - a - color textColor - display block - width 100% - padding 15px - box-sizing border-box - border-bottom solid 1px borderColor - text-decoration none - &:hover, &.hover - background-color hoverBackgroundColor - &:focus, &.focus - color black - &:active, &.active - color brandColor - &:last-child - border-bottom none - - -.PlanetBody - absolute bottom right - left 200px - top 65px