Merge branch 'wip-redesign'

# Conflicts:
#	src/templates/projects/view.pug
This commit is contained in:
2018-09-06 13:30:24 +02:00
80 changed files with 1750 additions and 3528 deletions

View File

@@ -6,20 +6,21 @@
| {% if node_type_name == 'group' %}
| {% set node_type_name = 'folder' %}
| {% endif %}
li(class="button-{{ node_type['name'] }}")
li.dropdown-item(class="button-{{ node_type['name'] }}")
a.item_add_node(
href="#",
title="{{ node_type['description'] }}",
data-node-type-name="{{ node_type['name'] }}",
data-toggle="tooltip",
data-placement="left")
href="#",
title="{{ node_type['description'] }}",
data-node-type-name="{{ node_type['name'] }}",
data-toggle="tooltip",
data-placement="left")
i.pi(class="icon-{{ node_type['name'] }}")
| {% if node_type_name == 'group_texture' %}
| Texture Folder
| {% elif node_type_name == 'group_hdri' %}
| HDRi Folder
| {% else %}
| {{ node_type_name }}
span.text-capitalize
|{{ node_type_name }}
| {% endif %}
| {% endif %}
| {% endfor %}

View File

@@ -28,15 +28,15 @@
span Add files...
input(type='file', name='file', multiple='')
button.btn.btn-primary.start(type='submit')
button.btn.btn-outline-primary.start(type='submit')
i.pi-upload
span Start upload
span Start Upload
button.btn.btn-warning.cancel(type='reset')
button.btn.btn-outline-warning.cancel(type='reset')
i.pi-cancel
span Cancel upload
span Cancel Upload
button.btn.btn-danger.delete(type='button')
button.btn.btn-outline-danger.delete(type='button')
i.pi-trash
span Delete

View File

@@ -23,7 +23,7 @@ script#template-upload(type="text/x-tmpl").
</button>
{% } %}
{% if (!i) { %}
<button class="btn btn-warning cancel">
<button class="btn btn-outline-secondary cancel">
<i class="ion-close-round"></i>
<span>Cancel</span>
</button>
@@ -61,7 +61,7 @@ script#template-download(type="text/x-tmpl").
</td>
<td>
{% if (file.deleteUrl) { %}
<button class="btn btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
<button class="btn btn-outline-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
<i class="ion-trash-b"></i>
<span>Delete</span>
</button>
@@ -71,7 +71,7 @@ script#template-download(type="text/x-tmpl").
Create
</div>
{% } else { %}
<button class="btn btn-warning cancel">
<button class="btn btn-outline-secondary cancel">
<i class="ion-close-round"></i>
<span>Cancel</span>
</button>

View File

@@ -1,26 +0,0 @@
| {% macro navigation_tabs(title) %}
nav#nav-tabs
ul#nav-tabs__list
li.nav-tabs__list-tab(
class="{% if title == 'homepage' %}active{% endif %}")
a(href="{{ url_for('main.homepage') }}") Activity
li.nav-tabs__list-tab(
class="{% if title == 'home' %}active{% endif %}")
a(href="{{ url_for('projects.home_project') }}") Home
li.nav-tabs__list-tab(
class="{% if title == 'dashboard' %}active{% endif %}")
a(href="{{ url_for('projects.index') }}") My Projects
| {% if current_user.has_organizations() %}
li.nav-tabs__list-tab(
class="{% if title == 'organizations' %}active{% endif %}")
a(
href="{{ url_for('pillar.web.organizations.index') }}",
title="My Organizations")
| My Organizations
| {% endif %}
| {% endmacro %}

View File

@@ -9,5 +9,5 @@
.modal-body
| ...
.modal-footer
button.btn.btn-default(type='button', data-dismiss='modal') Close
button.btn.btn-outline-secondary(type='button', data-dismiss='modal') Close
button.btn.btn-primary(type='button') Save changes

View File

@@ -66,10 +66,9 @@ html(lang="en")
| {% if not title %}{% set title="default" %}{% endif %}
body(class="{{ title }}")
.container-page
.page-content
.page-body
| {% block body %}{% endblock %}
.page-content
.page-body
| {% block body %}{% endblock %}
| {% block footer_container %}
#footer-container

View File

@@ -1,7 +1,7 @@
| {% block menu_body %}
| {% if current_user.is_authenticated %}
li(class="dropdown")
li.dropdown
| {% block menu_avatar %}
a.navbar-item.dropdown-toggle(href="#", data-toggle="dropdown", title="{{ current_user.email }}")
img.gravatar(
@@ -9,42 +9,38 @@ li(class="dropdown")
alt="Avatar")
| {% endblock menu_avatar %}
ul.dropdown-menu
ul.dropdown-menu.dropdown-menu-right
| {% if not current_user.has_role('protected') %}
| {% block menu_list %}
li
a.navbar-item(
href="{{ url_for('projects.home_project') }}"
title="Home")
i.pi-home
| Home
| #[i.pi-home] Home
li
a.navbar-item(
href="{{ url_for('projects.index') }}"
title="My Projects")
i.pi-star
| My Projects
| #[i.pi-star] My Projects
| {% if current_user.has_organizations() %}
li
a.navbar-item(
href="{{ url_for('pillar.web.organizations.index') }}"
title="My Organizations")
i.pi-users
| My Organizations
| #[i.pi-users] My Organizations
| {% endif %}
li
a.navbar-item(
href="{{ url_for('settings.profile') }}"
title="Settings")
i.pi-cog
| Settings
| #[i.pi-cog] Settings
| {% endblock menu_list %}
li.divider(role="separator")
li.dropdown-divider(role="separator")
| {% endif %}
li
@@ -59,8 +55,9 @@ li(class="dropdown")
| {% else %}
li.nav-item-sign-in
a.navbar-item(href="{{ url_for('users.login') }}")
| Log in
li.pt-1.pr-1
a.btn.btn-sm.btn-outline-primary.px-3(
href="{{ url_for('users.login') }}")
| Log In
| {% endif %}
| {% endblock menu_body %}

View File

@@ -5,21 +5,21 @@ section.node-preview-forbidden
div
p Available to Blender Cloud subscribers
hr
hr.bg-white
| {% if current_user.has_cap('can-renew-subscription') %}
p
small You have a subscription, it just needs to be renewed.
a.btn(href="/renew")
a.btn.btn-light(href="/renew")
| #[i.pi-heart] Renew Subscription
| {% else %}
p
small Support Blender and get awesome stuff!
a.btn(href="{{ url_for('cloud.join') }}")
a.btn.btn-light(href="{{ url_for('cloud.join') }}")
| #[i.pi-heart] Get a Subscription
| {% endif %}
| {% if current_user.is_anonymous %}
p(style="margin-top: 15px")
small
a(href="{{ url_for('users.login') }}") Already a subscriber? Log in
a.text-white(href="{{ url_for('users.login') }}") Already a subscriber? Log in
| {% endif %}

View File

@@ -61,7 +61,7 @@ script(type="text/javascript").
}
{% if node.has_method('PUT') %}
$('.project-mode-view').show();
$('.project-mode-view').displayAs('inline-block');
{% else %}
$('.project-mode-view').hide();
{% endif %}

View File

@@ -23,7 +23,7 @@ section.node-preview.video
| {% block node_download %}
| {% if node.file_variations %}
button.btn.btn-default.dropdown-toggle(
button.btn.btn-outline-secondary.dropdown-toggle(
type="button",
data-toggle="dropdown",
aria-haspopup="true",

View File

@@ -1,142 +0,0 @@
//- ******************************************************* -//
| {% import 'projects/_macros.html' as projectmacros %}
| {% macro render_blog_post(node, project=None, pages=None) %}
| {% if node.picture %}
a.blog_index-header(href="{{ node.url }}")
img(src="{{ node.picture.thumbnail('h', api=api) }}")
| {% endif %}
| {% if project and project._id != config.MAIN_PROJECT_ID %}
| {{ projectmacros.render_secondary_navigation(project, pages=pages) }}
| {% endif %}
.blog_index-item
a.item-title(
href="{{ node.url }}")
| {{ node.name }}
ul.meta
| {% if node.project.name %}
li {{ node.project.name }}
| {% endif %}
| {% if node.user.full_name%}
li.who
| by {{ node.user.full_name }}
| {% endif %}
li.when
a(href="{{ node.url }}",
title="Updated {{ node._updated | pretty_date }}")
| {{ node._created | pretty_date }}
li
a(href="{{ node.url }}#comments")
| comment
.item-content
| {{ node.properties | markdowned('content') }}
| {% endmacro %}
//- ******************************************************* -//
| {% macro render_blog_list_item(node) %}
.blog_index-item.list
| {% if node.picture %}
a.item-header(href="{{ node.url }}")
img.image(src="{{ node.picture.thumbnail('s', api=api) }}")
| {% else %}
a.item-header.nothumb(href="{{ node.url }}")
i.pi-document-text
| {% endif %}
a.item-title(
href="{{ node.url }}")
| {{node.name}}
.item-info.
#[span(title="{{node._created}}") {{node._created | pretty_date }}]
{% if node._created != node._updated %}
#[span(title="{{node._updated}}") (updated {{node._updated | pretty_date }})]
{% endif %}
{% if node.properties.category %} · {{node.properties.category}}{% endif %}
· {{node.user.full_name}}
{% if node.properties.status != 'published' %} · {{ node.properties.status}} {% endif %}
| {% endmacro %}
//- ******************************************************* -//
| {% macro render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta, pages=None) %}
| {% if can_create_blog_posts %}
.blog-action
a.btn.btn-default.button-create(href="{{url_for('nodes.posts_create', project_id=project._id)}}")
i.pi-plus
| Create New Post
| {% endif %}
| {% if posts %}
| {{ render_blog_post(posts[0], project=project, pages=pages) }}
| {% for node in posts[1:] %}
| {% if loop.first %}
.blog-archive-navigation
span Blasts from the past
| {% endif %}
| {{ render_blog_list_item(node) }}
| {% endfor %}
| {% if more_posts_available %}
.blog-archive-navigation
a(href="{{ project.blog_archive_url }}")
| {{posts_meta.total - posts|length}} more blog posts over here
i.pi-angle-right
| {% endif %}
| {% else %}
.blog_index-item
.item-content No posts... yet!
| {% endif %} {# posts #}
| {% endmacro %}
//- Macro for rendering the navigation buttons for prev/next pages -//
| {% macro render_archive_pagination(project) %}
.blog-archive-navigation
| {% if project.blog_archive_prev %}
a.archive-nav-button(
href="{{ project.blog_archive_prev }}", rel="prev")
i.pi-angle-left
| Previous page
| {% else %}
span.archive-nav-button
i.pi-angle-left
| Previous page
| {% endif %}
a.archive-nav-button(
href="{{ url_for('main.project_blog', project_url=project.url) }}")
| Blog Index
| {% if project.blog_archive_next %}
a.archive-nav-button(
href="{{ project.blog_archive_next }}", rel="next")
| Next page
i.pi-angle-right
| {% else %}
span.archive-nav-button
| Next page
i.pi-angle-right
| {% endif %}
| {% endmacro %}
| {% macro render_archive(project, posts, posts_meta) %}
| {{ render_archive_pagination(project) }}
| {% for node in posts %}
| {{ render_blog_list_item(node) }}
| {% endfor %}
| {{ render_archive_pagination(project) }}
| {% endmacro %}

View File

@@ -2,11 +2,8 @@
| {% import 'nodes/custom/blog/_macros.html' as blogmacros %}
| {% block body %}
.container-fluid
#blog_container.cloud-blog
#blog_index-container
.blog_index-header
h3 Blog Archive
.container
h3 Blog Archive
| {{ blogmacros.render_archive(project, posts, posts_meta) }}
| {{ blogmacros.render_archive(project, posts, posts_meta) }}
| {% endblock body %}

View File

@@ -9,9 +9,7 @@ link(href="{{ url_for('static_pillar', filename='assets/css/blog.css') }}", rel=
| {% endblock %}
| {% block project_context %}
#blog_container
#blog_index-container.expand-image-links
| {{ blogmacros.render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta) }}
| {{ blogmacros.render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta) }}
| {% endblock %}
| {% block project_tree %}

View File

@@ -10,10 +10,7 @@ link(href="{{ url_for('static_cloud', filename='assets/css/project-landing.css')
| {% endblock css %}
| {% block body %}
.container-fluid.blog
#blog_container.cloud-blog
#blog_index-container.expand-image-links
| {{ blogmacros.render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta, pages=pages) }}
| {{ blogmacros.render_blog_index(project, posts, can_create_blog_posts, api, more_posts_available, posts_meta, pages=pages) }}
| {% endblock %}
| {% block footer_scripts %}
@@ -25,7 +22,7 @@ script.
/* Expand images when their link points to a jpg/png/gif */
/* TODO: De-duplicate code from view post */
var page_overlay = document.getElementById('page-overlay');
$('.blog_index-item .item-content a img').on('click', function(e){
$('.item-content a img').on('click', function(e){
e.preventDefault();
var href = $(this).parent().attr('href');

View File

@@ -32,7 +32,6 @@
.comment-reply-preview-md
.comment-reply-info
.comment-action-cancel(
type="button",
title="{{ _('cancel') }}")
span {{ _('cancel') }}

View File

@@ -28,7 +28,7 @@ li.node-details-meta-list-item
| {% block node_download %}
| {% if node.properties.files %}
button.btn.btn-default.dropdown-toggle(
button.btn.btn-outline-secondary.dropdown-toggle(
title="Download HDRI",
type="button",
data-toggle="dropdown",

View File

@@ -68,9 +68,9 @@
| {% endif %}
| {% endfor %}
input.btn.btn-default.button-create(type='submit', value='Create {{ node_type.name }}')
input.btn.btn-outline-secondary(type='submit', value='Create {{ node_type.name }}')
a.btn.btn-default.button-back(href="{{ url_for('projects.view', project_url=project.url) }}blog")
a.btn.btn-link.button-back(href="{{ url_for('projects.view', project_url=project.url) }}blog")
| Back to Blog
#blog_post-create-container

View File

@@ -1,19 +1,9 @@
| {% import 'nodes/custom/blog/_macros.html' as blogmacros %}
#blog_container(class="{% if project and project._id == config.MAIN_PROJECT_ID %}cloud-blog{% endif %}")
| {{ blogmacros.render_blog_post(node, project=project) }}
#blog_index-container.expand-image-links
.blog-action
| {% if node.has_method('PUT') %}
a.btn.btn-default.button-edit(href="{{url_for('nodes.edit', node_id=node._id)}}")
i.pi-edit
| Edit Post
| {% endif %}
| {{ blogmacros.render_blog_post(node, project=project) }}
#comments-embed
.comments-list-loading
i.pi-spin
#comments-embed.comments-compact
.comments-list-loading
i.pi-spin
include ../_scripts

View File

@@ -26,8 +26,7 @@ link(href="{{ url_for('static_cloud', filename='assets/css/project-landing.css')
| {% set title = 'blog' %}
| {% block body %}
.container-fluid.blog
| {% include 'nodes/custom/post/view_embed.html' %}
| {% include 'nodes/custom/post/view_embed.html' %}
| {% endblock %}

View File

@@ -91,11 +91,11 @@
a(href="{{ f.file.link }}",,
title="Download texture",
download="{{ f.file.filename }}")
button.btn.btn-default(type="button")
button.btn.btn-outline-secondary(type="button")
i.pi-download
| Download
| {% else %}
button.btn.btn-default.disabled.sorry(type="button")
button.btn.btn-outline-secondary.disabled.sorry(type="button")
i.pi-lock
| Download
| {% endif %}

View File

@@ -38,18 +38,21 @@
| {% elif field.type == 'HiddenField' %}
| {{ field }}
| {% elif field.name == 'attachments' %}
hr
#attachments-actions
.btn.btn-info#attachments-action-add
i.pi-plus
| Add New Attachment
p.text-muted
p.text-muted.mt-3
| Attachments can be included in any MarkDown field by using the #[code {attachment slug}] shortcode
| (#[a(href='https://pillarframework.org/shortcodes/#attachments', target='_blank') help]).
| This shortcode is placed on your copy-paste buffer by clicking "Copy to clipboard".
| {{ render_field(field, field.name) }}
hr
| {% elif field.name == 'files' %}
#files-actions
@@ -66,20 +69,23 @@
| {% endfor %}
ul.project-edit-tools.bottom
hr
ul.project-edit-tools.justify-content-end.h-auto
li.button-cancel
a#item_cancel.item-cancel.project-mode-edit(
a#item_cancel.item-cancel.project-mode-edit.btn.btn-outline-secondary(
href="javascript:void(0);",
title="Cancel changes")
i.button-cancel-icon.pi-cancel
| Cancel
li.button-save
a#item_save.item-save.project-mode-edit(
a#item_save.item-save.project-mode-edit.btn.btn-outline-success.ml-2(
href="javascript:void(0);",
title="Save changes")
i.button-save-icon.pi-check
| Save Changes
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.ui.widget.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.iframe-transport.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.fileupload.min.js') }}")

View File

@@ -1,210 +1,10 @@
| {% extends 'layout.html' %}
| {% from '_macros/_navigation.html' import navigation_tabs %}
| {% set title = 'organizations' %}
| {% block page_title %}Organizations{% endblock %}
| {% block og %}
meta(property="og:title", content="Dashboard")
meta(name="twitter:title", content="Blender Cloud")
meta(property="og:url", content="https://cloud.blender.org/{{ request.path }}")
meta(property="og:type", content="website")
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
| {% endblock %}
| {% block body %}
.dashboard-container
section.dashboard-main
| {{ navigation_tabs(title) }}
section#projects
| {% if can_create_organization %}
nav#sub-nav-tabs.projects
ul#sub-nav-tabs__list
li.result#create_organization_result_panel
li.create
button.btn.btn-success(onclick='createNewOrganization(this)')
i.pi-plus
| Create Organization
| {% endif %}
nav.nav-tabs__tab.active#own_projects
ul.projects__list
| {% if organizations %}
| {% for organization in organizations['_items'] %}
| {% set link_url = url_for('pillar.web.organizations.view_embed', organization_id=organization._id) %}
li.projects__list-item(
data-url="{{ link_url }}",
id="organization-{{ organization._id }}")
a.projects__list-thumbnail(
href="{{ link_url }}")
i.pi-users
.projects__list-details
a.title(href="{{ link_url }}")
| {{ organization.name }}
ul.meta
li(title="Members")
| {{ organization.members|hide_none|count }} Member{{ organization.members|hide_none|count|pluralize }}
| {% if (organization.unknown_members|count) != 0 %}
| ({{ organization.unknown_members|hide_none|count }} pending)
| {% endif %}
li(title="Seats")
| {{ organization.seat_count }} Seat{{ organization.seat_count|pluralize }}
| {% endfor %}
| {% else %}
li.projects__list-item
a.projects__list-thumbnail
i.pi-blender-cloud
.projects__list-details
span Create an Organization to get started!
| {% endif %}
section.dashboard-secondary
section.box
#item-details
| {% endblock %}
| {% block footer_scripts %}
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.typeahead-0.11.1.min.js')}}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.autocomplete-0.22.0.min.js') }}", async=true)
script.
/* Returns a more-or-less reasonable message given an error response object. */
function xhrErrorResponseMessage(err) {
if (typeof err.responseJSON == 'undefined')
return err.statusText;
if (typeof err.responseJSON._error != 'undefined' && typeof err.responseJSON._error.message != 'undefined')
return err.responseJSON._error.message;
if (typeof err.responseJSON._message != 'undefined')
return err.responseJSON._message
return err.statusText;
}
/**
* Open an organization in the #item-details div.
*/
function item_open(item_id, pushState)
{
if (item_id === undefined ) {
throw new ReferenceError("item_open(" + item_id + ") called.");
}
// Style elements starting with item_type and dash, e.g. "#job-uuid"
var clean_classes = 'active processing';
var current_item = $('#organization-' + item_id);
$('[id^="organization-"]').removeClass(clean_classes);
current_item
.removeClass(clean_classes)
.addClass('processing');
var item_url = '/o/' + item_id;
$.get(item_url, function(item_data) {
$('#item-details').html(item_data);
current_item
.removeClass(clean_classes)
.addClass('active');
}).fail(function(xhr) {
if (console) {
console.log('Error fetching organization', item_id, 'from', item_url);
console.log('XHR:', xhr);
}
current_item.removeClass(clean_classes);
toastr.error('Failed to open organization');
if (xhr.status) {
$('#item-details').html(xhr.responseText);
} else {
$('#item-details').html('<p class="text-danger">Opening ' + item_type + ' failed. There possibly was ' +
'an error connecting to the server. Please check your network connection and ' +
'try again.</p>');
}
});
// Determine whether we should push the new state or not.
pushState = (typeof pushState !== 'undefined') ? pushState : true;
if (!pushState) return;
// Push the correct URL onto the history.
var push_state = {itemId: item_id};
window.history.pushState(
push_state,
'Organization: ' + item_id,
item_url
);
}
$('li.projects__list-item').click(function(e){
url = $(this).data('url');
if (typeof url === 'undefined') return;
window.location.href = url;
if (console) console.log(url);
$(this).addClass('active');
$(this).find('.projects__list-thumbnail i')
.removeAttr('class')
.addClass('pi-spin spin');
});
{% if open_organization_id %}
$(function() { item_open('{{ open_organization_id }}', false); });
{% endif %}
{% if can_create_organization %}
function createNewOrganization(button) {
$(button)
.attr('disabled', 'disabled')
.fadeTo(200, 0.1);
$('#create_organization_result_panel').html('');
// TODO: create a form to get the initial info from the user.
$.post(
'{{ url_for('pillar.web.organizations.create_new') }}',
{
name: 'New Organization',
seat_count: 1,
}
)
.done(function(result) {
var $p = $('<p>').text('organization created, reloading list.')
$('#create_organization_result_panel').html($p);
window.location.href = result.location;
})
.fail(function(err) {
var msg = xhrErrorResponseMessage(err);
$('#create_organization_result_panel').html('Error creating organization: ' + msg);
$(button)
.fadeTo(1000, 1.0)
.queue(function() {
$(this)
.removeAttr('disabled')
.dequeue()
;
})
})
;
return false;
}
{% endif %}
.p-5.text-center
h2 Organizations Index
.lead.
See Blender Cloud template for reference.
| {% endblock %}

View File

@@ -75,7 +75,7 @@
script $('#admin-picker').hide();
.input-group
button#item-save.btn.btn-success.btn-block(type='submit')
button#item-save.btn.btn-outline-success.btn-block(type='submit')
i.pi-check
| Save Changes
| {% else %}

View File

@@ -1,42 +1,41 @@
| {% macro render_secondary_navigation(project, pages=None) %}
nav.navbar-secondary
.navbar-container
nav.collapse.navbar-collapse
ul.nav.navbar-nav.navbar-right
li
a.navbar-item(
href="{{ url_for('projects.view', project_url=project.url) }}",
title="{{ project.name }} Homepage")
span
b {{ project.name }}
li
a.navbar-item(
href="{{ url_for('main.project_blog', project_url=project.url) }}",
title="Project Blog",
class="{% if category == 'blog' %}active{% endif %}")
span Blog
| {% if pages %}
| {% for p in pages %}
li
a.navbar-item(
href="{{ url_for('projects.view_node', project_url=project.url, node_id=p._id) }}",
title="{{ p.name }}",
class="{% if category == 'page' %}active{% endif %}")
span {{ p.name }}
| {% endfor %}
| {% endif %}
| {% if project.nodes_featured %}
| {# In some cases featured_nodes might might be embedded #}
| {% if '_id' in project.nodes_featured[0] %}
| {% set featured_node_id=project.nodes_featured[0]._id %}
| {% else %}
| {% set featured_node_id=project.nodes_featured[0] %}
| {% endif %}
li
a.navbar-item(
href="{{ url_for('projects.view_node', project_url=project.url, node_id=featured_node_id) }}",
title="Explore {{ project.name }}",
class="{% if category == 'blog' %}active{% endif %}")
span Explore
| {% endif %}
nav.collapse.navbar-collapse
ul.navbar-nav.navbar-right
li
a.navbar-item(
href="{{ url_for('projects.view', project_url=project.url) }}",
title="{{ project.name }} Homepage")
span
b {{ project.name }}
li
a.navbar-item(
href="{{ url_for('main.project_blog', project_url=project.url) }}",
title="Project Blog",
class="{% if category == 'blog' %}active{% endif %}")
span Blog
| {% if pages %}
| {% for p in pages %}
li
a.navbar-item(
href="{{ url_for('projects.view_node', project_url=project.url, node_id=p._id) }}",
title="{{ p.name }}",
class="{% if category == 'page' %}active{% endif %}")
span {{ p.name }}
| {% endfor %}
| {% endif %}
| {% if project.nodes_featured %}
| {# In some cases featured_nodes might might be embedded #}
| {% if '_id' in project.nodes_featured[0] %}
| {% set featured_node_id=project.nodes_featured[0]._id %}
| {% else %}
| {% set featured_node_id=project.nodes_featured[0] %}
| {% endif %}
li
a.navbar-item(
href="{{ url_for('projects.view_node', project_url=project.url, node_id=featured_node_id) }}",
title="Explore {{ project.name }}",
class="{% if category == 'blog' %}active{% endif %}")
span Explore
| {% endif %}
| {% endmacro %}

View File

@@ -7,17 +7,16 @@ span#project-edit-title
| Edit Project
ul.project-edit-tools
// Edit Mode
li.button-cancel
a#item_cancel.project-mode-edit(
a#item_cancel.project-mode-edit.btn.btn-sm.btn-link(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}",
title="Cancel changes")
i.button-cancel-icon.pi-back
i.button-cancel-icon.pi-angle-left
| Go to Project
li.button-save
a#item_save.project-mode-edit(
a#item_save.project-mode-edit.btn.btn-sm.btn-outline-success.mx-2(
href="#",
title="Save changes")
i.button-save-icon.pi-check
@@ -80,16 +79,18 @@ ul.project-edit-tools
| {% endfor %}
ul.project-edit-tools.bottom
hr
ul.project-edit-tools.justify-content-end.h-auto
li.button-cancel
a#item_cancel.project-mode-edit(
a#item_cancel.project-mode-edit.btn.btn-link(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}",
title="Cancel changes")
i.button-cancel-icon.pi-back
i.button-cancel-icon.pi-angle-left
| Go to Project
li.button-save
a#item_save.project-mode-edit(
a#item_save.project-mode-edit.btn.btn-outline-success.ml-2(
href="#",
title="Save changes")
i.button-save-icon.pi-check
@@ -97,6 +98,8 @@ ul.project-edit-tools
| {% endblock %}
| {% block footer_container %}{% endblock %}
| {% block footer_scripts %}
script(type='text/javascript', src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.ui.widget.min.js') }}")
script(type='text/javascript', src="{{ url_for('static_pillar', filename='assets/js/vendor/jquery.iframe-transport.min.js') }}")
@@ -105,7 +108,8 @@ script(type='text/javascript', src="{{ url_for('static_pillar', filename='assets
script(type="text/javascript").
$('.project-mode-edit').show();
// Show edit mode buttons (save, cancel).
$('.project-mode-edit').displayAs('inline-block');
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: true, nodeId: ''});
var convert = new Markdown.getSanitizingConverter().makeHtml;

View File

@@ -5,7 +5,7 @@
#project-container
#project-side-container
#project_sidebar
ul.project-tabs
ul.project-tabs.p-0
li.tabs-thumbnail(
title="About",
data-toggle="tooltip",
@@ -51,13 +51,13 @@
#project_nav
#project_nav-container
#project_nav-header
.project-title
a(href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| {{ project.name }}
#project_nav-header.bg-white
a.project-title.p-2.font-weight-bold.text-dark(
href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| {{ project.name }}
// TODO - make list a macro
#project_tree.edit
#project_tree.edit.bg-white
ul.project_nav-edit-list
li(class="{% if title == 'edit' %}active{% endif %}")
a(href="{{ url_for('projects.edit', project_url=project.url) }}")
@@ -77,10 +77,9 @@
i(class="pi-{{ext.icon}}")
| {{ext.name | title}}
| {% endfor %}
.project_split(title="Toggle Navigation [T]")
#project_context-container
#project_context-header
#project_context-header.bg-white
span#status-bar
| {% block project_context_header %}
| {% endblock %}

View File

@@ -19,7 +19,7 @@ form(
.col-md-9
h3 Editing: {{ node_type['name'] }}
.col-md-3
button.js-form-save.btn.btn-success.pull-right(style="margin-top: 15px;")
button.js-form-save.btn.btn-outline-success.pull-right(style="margin-top: 15px;")
| Save Changes
.row
@@ -46,7 +46,7 @@ form(
| {% endif %}
| {% endfor %}
button.js-form-save.btn.btn-success.pull-right
button.js-form-save.btn.btn-outline-success.pull-right
| Save Changes

View File

@@ -80,7 +80,7 @@ section.nav-tabs__tab.active#tab-images
Image Sharing requires a Blender Cloud subscription.
.buttons
a.btn.btn-default.btn-outline.green(href="https://store.blender.org/product/membership/")
a.btn.btn-outline-primary(href="https://store.blender.org/product/membership/")
| Join Now
| {% endif %}
| {% endblock %}

View File

@@ -1,43 +1,8 @@
| {% extends 'projects/home_layout.html' %}
| {% set subtab = 'blender_sync' %}
| {% set learn_more_btn_url = '/blog/introducing-blender-sync' %}
| {% block currenttab %}
section.nav-tabs__tab.active#tab-blender_sync
.tab_header-container
.tab_header-intro(
style="background-image: url({{ url_for('static', filename='assets/img/backgrounds/pattern_01.jpg')}})")
.tab_header-intro_text
h2 Connect Blender with the Cloud
p
| Save your Blender preferences once, load them anywhere.
<br/>
| Use the
=' '
a(href='https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip') Blender Cloud add-on
=' '
| to synchronise your settings from within Blender.
.tab_header-intro_icons
i.pi-blender
i.pi-heart-filled
i.pi-blender-cloud
| {% for version in synced_versions %}
.blender_sync-main
.blender_sync-main-header
h2.blender_sync-main-title
i.pi-blender
| Blender {{ version.version }}
.blender_sync-main-last
| Last synced on: {{ version.date|pretty_date }}
| {% else %}
.blender_sync-main.empty
.blender_sync-main-header
span.blender_sync-main-title
| No settings synced yet
<hr/>
a.download(
href='https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip')
| Download add-on
| {% endfor %}
.p-5.text-center
h2 Home Index
p.lead.
See Blender Cloud for reference.
| {% endblock %}

View File

@@ -1,77 +1,15 @@
| {% extends 'layout.html' %}
| {% from '_macros/_navigation.html' import navigation_tabs %}
| {% set title = 'home' %}
| {% block og %}
meta(property="og:type", content="website")
meta(property="og:url", content="https://cloud.blender.org{{ request.path }}")
meta(property="og:title", content="Blender Cloud - Home")
meta(name="twitter:title", content="Blender Cloud")
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
| {% endblock %}
| {% block page_title %}
| {{current_user.full_name}}
| {% endblock %}
| {% block body %}
.dashboard-container
section.dashboard-main
| {{ navigation_tabs(title) }}
.p-5.text-center
h2 Home Layout
p.lead.
See Blender Cloud for reference.
section#projects
nav#sub-nav-tabs.home
ul#sub-nav-tabs__list
li.nav-tabs__list-tab#subtab-blender_sync(data-tab-url="{{ url_for('projects.home_project')}}")
i.pi-blender
| Blender Sync
li.nav-tabs__list-tab#subtab-images(data-tab-url="{{ url_for('projects.home_project_shared_images')}}")
i.pi-picture
| Images
| {% block currenttab %}{% endblock %}
section.dashboard-secondary
section.announcement
img.header(
src="{{ url_for('static', filename='assets/img/blender_sync_header.jpg') }}")
.text
| {% block side_announcement %}
.title
a(href="https://cloud.blender.org/blog/introducing-blender-sync") Blender Sync
.lead
span.
Save your settings once. Use them anywhere.
Carry your Blender configuration with you, use our free add-on to sync your keymaps and preferences.
<hr/>
Syncing is free for everyone. No subscription required.
| {% endblock %}
| {% if show_addon_download_buttons %}
.buttons
a.btn.btn-default.btn-outline.orange(
href="https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip")
i.pi-download
| Download <small>v</small>{{ config.BLENDER_CLOUD_ADDON_VERSION }}
a.btn.btn-default.btn-outline.blue(
href="{{ learn_more_btn_url }}")
| Learn More
| {% endif %}
| {% endblock %}
| {% block footer_scripts %}
script.
$(document).ready(function () {
$('#subtab-{{ subtab }}').addClass('active');
var $nav_tabs = $('#sub-nav-tabs__list').find('li.nav-tabs__list-tab');
$nav_tabs.on('click', function (e) {
window.location = $(this).attr('data-tab-url');
});
});
| {% block currenttab %}{% endblock currenttab %}
| {% endblock %}

View File

@@ -1,347 +1,16 @@
| {% extends 'layout.html' %}
| {% from '_macros/_navigation.html' import navigation_tabs %}
| {% set title = 'dashboard' %}
| {% block og %}
meta(property="og:title", content="Dashboard")
meta(name="twitter:title", content="Blender Cloud")
meta(property="og:url", content="https://cloud.blender.org/{{ request.path }}")
meta(property="og:type", content="website")
meta(property="og:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
meta(name="twitter:image", content="{{ url_for('static', filename='assets/img/backgrounds/cloud_services_oti.jpg')}}")
| {% endblock %}
| {% block page_title %}
| {{current_user.full_name}}
| {% endblock %}
| {% block css %}
| {{ super() }}
style.
.deleted-projects-toggle {
z-index: 10;
position: absolute;
right: 0;
font-size: 20px;
padding: 3px;
text-shadow: 0 0 2px white;
}
.deleted-projects-toggle .show-deleted {
color: #aaa;
}
.deleted-projects-toggle .hide-deleted {
color: #bbb;
}
| {% endblock %}
| {% block body %}
.dashboard-container
section.dashboard-main
| {{ navigation_tabs(title) }}
section#projects
nav#sub-nav-tabs.projects
ul#sub-nav-tabs__list
li.nav-tabs__list-tab.active(data-tab-toggle='own_projects')
| Own Projects
| {% if projects_user|length != 0 %}
span ({{ projects_user|length }})
| {% endif %}
li.nav-tabs__list-tab(data-tab-toggle='shared')
| Shared with me
| {% if projects_shared|length != 0 %}
span ({{ projects_shared|length }})
| {% endif %}
| {% if current_user.has_cap('subscriber') %}
li.create#project-create(
data-url="{{ url_for('projects.create') }}")
a.btn.btn-success(
href="{{ url_for('projects.create') }}")
i.pi-plus
| Create Project
| {% elif current_user.has_cap('can-renew-subscription') %}
li.create
a.btn(href="/renew", target="_blank")
i.pi-heart
| Renew subscription to create a project
| {% endif %}
nav.nav-tabs__tab.active#own_projects
.deleted-projects-toggle
| {% if show_deleted_projects %}
a.hide-deleted(href="{{ request.base_url }}", title='Hide deleted projects')
i.pi-trash
| {% else %}
a.show-deleted(href="{{ request.base_url }}?deleted=1", title='Show deleted projects')
i.pi-trash
| {% endif %}
ul.projects__list
| {% for project in projects_deleted %}
li.projects__list-item.deleted
span.projects__list-thumbnail
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
| {% else %}
i.pi-blender-cloud
| {% endif %}
.projects__list-details
span.title {{ project.name }}
ul.meta
li.status.deleted Deleted
li.edit
a(href="javascript:undelete_project('{{ project._id }}')") Restore project
| {% else %}
| {% if show_deleted_projects %}
li.projects__list-item.deleted You have no recenly deleted projects. Deleted projects can be restored within a month after deletion.
| {% endif %}
| {% endfor %}
| {% for project in projects_user %}
li.projects__list-item(
data-url="{{ url_for('projects.view', project_url=project.url) }}")
a.projects__list-thumbnail(
href="{{ url_for('projects.view', project_url=project.url) }}")
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
| {% else %}
i.pi-blender-cloud
| {% endif %}
.projects__list-details
a.title(href="{{ url_for('projects.view', project_url=project.url) }}")
| {{ project.name }}
ul.meta
li.status(
class="{{ project.is_private | yesno('private,public,') }}",
title="{{ project.is_private | yesno('Private Project,Public Project,') }}")
| {{ project.is_private | yesno('Private,Public,') }}
li.when(title="{{ project._created }}") {{ project._created | pretty_date }}
li.edit
a(href="{{ url_for('projects.edit', project_url=project.url) }}") Edit
| {% if project.status == 'pending' and current_user.has_cap('view-pending-nodes') %}
li.pending Not Published
| {% endif %}
| {% else %}
| {% if current_user.has_cap('subscriber') %}
li.projects__list-item(data-url="{{ url_for('projects.create') }}")
a.projects__list-thumbnail
i.pi-plus
.projects__list-details
a.title(href="{{ url_for('projects.create') }}")
| Create a project to get started!
| {% elif current_user.has_cap('can-renew-subscription') %}
li.projects__list-item(data-url="https://store.blender.org/renew-my-subscription.php")
a.projects__list-thumbnail
i.pi-plus
.projects__list-details
a.title(href="https://store.blender.org/renew-my-subscription.php")
| Renew your Blender Cloud subscription to create your own projects!
| {% else %}
li.projects__list-item(data-url="/join")
a.projects__list-thumbnail
i.pi-plus
.projects__list-details
a.title(href="/join")
| Join Blender Cloud to create your own projects!
| {% endif %}
| {% endfor %}
section.nav-tabs__tab#shared(style='display: none')
ul.projects__list
| {% if projects_shared %}
| {% for project in projects_shared %}
li.projects__list-item(
data-url="{{ url_for('projects.view', project_url=project.url) }}")
a.projects__list-thumbnail(
href="{{ url_for('projects.view', project_url=project.url) }}")
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('s', api=api) }}")
| {% else %}
i.pi-blender-cloud
| {% endif %}
.projects__list-details
a.title(href="{{ url_for('projects.view', project_url=project.url) }}")
| {{ project.name }}
ul.meta
li.status(
class="{{ project.is_private | yesno('private,public,') }}",
title="{{ project.is_private | yesno('Private Project,Public Project,') }}")
| {{ project.is_private | yesno('Private,Public,') }}
li.when {{ project._created | pretty_date }}
li.who by {{ project.user.full_name }}
li.edit
a(href="{{ url_for('projects.edit', project_url=project.url) }}") Edit
| {% if project.status == 'pending' and current_user.has_cap('view-pending-nodes') %}
li.pending Not Published
| {% endif %}
li.leave
span.user-remove-prompt
| Leave Project
span.user-remove
| Are you sure?
span.user-remove-confirm(
user-id="{{ current_user.objectid }}",
project-url="{{url_for('projects.sharing', project_url=project.url)}}")
i.pi-check
| Yes, leave
span.user-remove-cancel
i.pi-cancel
| No, cancel
| {% endfor %}
| {% else %}
li.projects__list-item
a.projects__list-thumbnail
i.pi-heart-broken
.projects__list-details
.title
| No projects shared with you... yet!
| {% endif %}
section.dashboard-secondary
section.announcement
img.header(
src="{{ url_for('static', filename='assets/img/backgrounds/services_projects.jpg')}}")
.text
.title Projects
.lead
span.
Create and manage your own personal projects.
Upload assets and collaborate with other Blender Cloud members.
.buttons
a.btn.btn-default.btn-outline.blue(
href="https://cloud.blender.org/blog/introducing-private-projects")
| Learn More
section.announcement
a(href="https://cloud.blender.org/blog/introducing-blender-sync")
img.header(
src="{{ url_for('static', filename='assets/img/blender_sync_header.jpg') }}")
.text
.title
a(href="https://cloud.blender.org/blog/introducing-blender-sync") Textures Browser & Settings Sync
.lead
span.
Get the official Blender Cloud add-on:
ul
li Save your Blender settings online, use them anywhere
li Browse over 800 textures & HDRIs within Blender
li Share Screenshots & Renders directly to Blender Cloud
.buttons
a.btn.btn-default.btn-outline.orange(
href="https://cloud.blender.org/r/downloads/blender_cloud-latest-bundle.zip")
i.pi-download
| Download Add-on <small>v</small> {{ config.BLENDER_CLOUD_ADDON_VERSION }}
a.btn.btn-default.btn-outline.blue(
href="https://cloud.blender.org/blog/introducing-blender-sync")
| Learn More
.p-5.text-center
h2 Index Dashboard
p.lead.
See Blender Cloud template for reference.
| {% endblock %}
| {% block footer_scripts %}
script.
$(document).ready(function() {
$('li.projects__list-item').click(function(e){
url = $(this).data('url');
if (typeof url === 'undefined') return;
window.location.href = url;
if (console) console.log(url);
$(this).addClass('active');
$(this).find('.projects__list-thumbnail i')
.removeAttr('class')
.addClass('pi-spin spin');
});
// Tabs behavior
var $nav_tabs_list = $('#sub-nav-tabs__list');
var $nav_tabs = $nav_tabs_list.find('li.nav-tabs__list-tab');
$nav_tabs.on('click', function(e){
e.preventDefault();
$nav_tabs.removeClass('active');
$(this).addClass('active');
$('.nav-tabs__tab').hide();
$('#' + $(this).attr('data-tab-toggle')).show();
});
// Create project
$('#project-create').on('click', function(e){
e.preventDefault();
$(this).addClass('disabled');
$('a', this).html('<i class="pi-spin spin"></i> Creating project...');
window.location.href = $(this).data('url');
});
// Leave project
var $projects_list = $('ul.projects__list');
$projects_list.find('span.user-remove-prompt').on('click', function(e){
e.stopPropagation();
e.preventDefault();
$(this).next().show();
$(this).hide();
});
$projects_list.find('span.user-remove-cancel').on('click', function(e){
e.stopPropagation();
e.preventDefault();
$(this).parent().prev().show();
$(this).parent().hide();
});
$projects_list.find('span.user-remove-confirm').on('click', function(e){
e.stopPropagation();
e.preventDefault();
var parent = $(this).closest('.projects__list-item');
function removeUser(userId, projectUrl){
$.post(projectUrl, {user_id: userId, action: 'remove'})
.done(function (data) {
parent.remove();
});
}
removeUser($(this).attr('user-id'), $(this).attr('project-url'));
});
hopToTop(); // Display jump to top button
});
var patch_url = '{{ url_for('projects.patch.patch_project', project_id='PROJECTID') }}';
function undelete_project(project_id) {
console.log('undeleting project', project_id);
$.ajax({
url: patch_url.replace('PROJECTID', project_id),
method: 'PATCH',
data: JSON.stringify({'op': 'undelete'}),
contentType: 'application/json'
})
.done(function(data, textStatus, jqXHR) {
location.href = jqXHR.getResponseHeader('Location');
})
.fail(function(err) {
toastr.error(xhrErrorResponseMessage(err), 'Undeletion failed');
})
}
| {% endblock %}

View File

@@ -1,642 +1,10 @@
| {% extends 'layout.html' %}
| {% from '_macros/_add_new_menu.html' import add_new_menu %}
| {% block page_title %}{{ project.name }}{% endblock%}
| {% block og %}
meta(property="og:type", content="website")
| {% if og_picture %}
meta(property="og:image", content="{{ og_picture.thumbnail('l', api=api) }}")
meta(name="twitter:image", content="{{ og_picture.thumbnail('l', api=api) }}")
| {% elif node and node.picture %}
meta(property="og:image", content="{{ node.picture.thumbnail('l', api=api) }}")
meta(name="twitter:image", content="{{ node.picture.thumbnail('l', api=api) }}")
| {% elif project.picture_header %}
meta(property="og:image", content="{{ project.picture_header.thumbnail('l', api=api) }}")
meta(name="twitter:image", content="{{ project.picture_header.thumbnail('l', api=api) }}")
| {% endif %}
| {% if show_project %}
meta(property="og:title", content="{{ project.name }} - Blender Cloud")
meta(name="twitter:title", content="{{ project.name }} - Blender Cloud")
meta(property="og:description", content="{{ project.summary }}")
meta(name="twitter:description", content="{{ project.summary }}")
meta(property="og:url", content="{{ url_for('projects.view', project_url=project.url, _external=True) }}")
| {% else %}
| {% if node %}
meta(property="og:title", content="{{ node.name }} - Blender Cloud")
meta(name="twitter:title", content="{{ node.name }} on Blender Cloud")
| {% if node.node_type == 'post' %}
| {% if node.properties.content %}
meta(property="og:description", content="{{ node.properties.content | truncate(180) }}")
meta(name="twitter:description", content="{{ node.properties.content | truncate(180) }}")
| {% else %}
meta(property="og:description", content="Blender Cloud, your source for open content and training")
meta(name="twitter:description", content="Blender Cloud, your source for open content and training")
| {% endif %}
| {% else %}
| {% if node.description %}
meta(property="og:description", content="{{ node.description | truncate(180) }}")
meta(name="twitter:description", content="{{ node.description | truncate(180) }}")
| {% else %}
meta(property="og:description", content="Blender Cloud, your source for open content and training")
meta(name="twitter:description", content="Blender Cloud, your source for open content and training")
| {% endif %}
| {% endif %}
meta(property="og:url", content="{{url_for('projects.view_node', project_url=project.url, node_id=node._id)}}")
| {% else %}
meta(property="og:title", content="{{ project.name }} Blog on Blender Cloud")
meta(name="twitter:title", content="{{ project.name }} Blog on Blender Cloud")
meta(property="og:description", content="{{ project.summary }}")
meta(name="twitter:description", content="{{ project.summary }}")
meta(property="og:url", content="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| {% endif %}
| {% endif %}
| {% endblock %}
| {% block head %}
link(href="{{ url_for('static_pillar', filename='assets/jstree/themes/default/style.min.css') }}", rel="stylesheet")
| {% if node %}
link(rel="amphtml", href="{{ url_for('nodes.view', node_id=node._id, _external=True, format='amp') }}")
| {% endif %}
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-6.2.8.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-ga-0.4.2.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/vendor/videojs-hotkeys-0.2.20.min.js') }}")
script(src="{{ url_for('static_pillar', filename='assets/js/video_plugins.min.js') }}")
| {% endblock %}
| {% block css %}
link(href="{{ url_for('static_pillar', filename='assets/css/font-pillar.css') }}", rel="stylesheet")
link(href="{{ url_for('static_pillar', filename='assets/css/base.css') }}", rel="stylesheet")
link(href="{{ url_for('static_pillar', filename='assets/css/project-main.css') }}", rel="stylesheet")
| {% endblock %}
| {% set title = 'project' %}
| {% block body %}
#project-container
#project-side-container
#project_sidebar
ul.project-tabs
li.tabs-thumbnail(class="{% if project.picture_square %}image{% endif %}")
a(href="{{url_for('projects.view', project_url=project.url)}}")
#project-loading
i.pi-spin
| {% if project.picture_square %}
img(src="{{ project.picture_square.thumbnail('b', api=api) }}")
| {% else %}
i.pi-home
| {% endif %}
li.tabs-browse(
title="Browse",
data-toggle="tooltip",
data-placement="right",
class="active")
a(href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
i.pi-folder
| {% if not project.is_private %}
| {% if current_user_is_subscriber %}
li.tabs-search(
title="Search",
data-toggle="tooltip",
data-placement="right")
a(href="{{ url_for('projects.search', project_url=project.url, _external=True)}} ")
i.pi-search
| {% else %}
li.tabs-search(
title="Search (subscribers only)",
data-toggle="tooltip",
data-placement="right")
a(href="{{ url_for('cloud.join') }}")
i.pi-search
| {% endif %}
| {% endif %}
| {{ extension_sidebar_links }}
| {% if project.has_method('PUT') %}
li(
title="Edit Project",
data-toggle="tooltip",
data-placement="right")
a(href="{{ url_for('projects.edit', project_url=project.url) }}")
i.pi-cog
| {% endif %}
#project_nav(class="{{ title }}")
#project_nav-container
| {% if title != 'about' %}
#project_nav-header
.project-title
a(href="{{url_for('projects.view', project_url=project.url, _external=True)}}")
| {{ project.name }}
| {% block project_tree %}
#project_tree
| {% endblock project_tree %}
| {% endif %}
#project_context-container
| {% if project.has_method('PUT') %}
#project_context-header
span#status-bar
ul.project-edit-tools.disabled
li.button-dropdown
a#item_add.dropdown-toggle.project-mode-view(
type="button",
data-toggle="dropdown",
aria-haspopup="true",
aria-expanded="false")
i.button-add-icon.pi-collection-plus
| New...
ul.dropdown-menu.add_new-menu
| {{ add_new_menu(project.node_types) }}
li.button-edit
a#item_edit.project-mode-view(
href="javascript:void(0);",
title="Edit",
data-project_id="{{project._id}}")
i.button-edit-icon.pi-edit
| Edit Project
li.button-dropdown
a.dropdown-toggle.project-mode-view(
type="button",
data-toggle="dropdown",
aria-haspopup="true",
aria-expanded="false")
i.pi-more-vertical
ul.dropdown-menu
| {% if current_user.has_cap('admin') %}
li.button-featured
a#item_featured(
href="javascript:void(0);",
title="Feature on project's homepage",
data-toggle="tooltip",
data-placement="left")
i.button-featured-icon.pi-star
| Toggle Featured
li.button-toggle-public
a#item_toggle_public(
href="javascript:void(0);",
title="Make it accessible to anyone",
data-toggle="tooltip",
data-placement="left")
i.pi-lock-open
| Toggle public
| {% endif %}
li.button-toggle-projheader
a#item_toggle_projheader(
href="javascript:void(0);",
title="Feature as project's header",
data-toggle="tooltip",
data-placement="left")
i.button-featured-icon.pi-star
| Toggle Project Header video
li.button-move
a#item_move(
href="javascript:void(0);",
title="Move into a folder...",
data-toggle="tooltip",
data-placement="left")
i.button-move-icon.pi-move
| Move
li.button-delete
a#item_delete(
href="javascript:void(0);",
title="Can be undone within a month",
data-toggle="tooltip",
data-placement="left")
i.pi-trash
| Delete Project
// Edit Mode
li.button-cancel
a#item_cancel.project-mode-edit(
href="javascript:void(0);",
title="Cancel changes")
i.button-cancel-icon.pi-cancel
| Cancel
li.button-save
a#item_save.project-mode-edit(
href="javascript:void(0);",
title="Save changes")
i.button-save-icon.pi-check
| Save Changes
| {% endif %}
| {% set utm_source = request.args.get('utm_source') %}
| {% if config.UTM_LINKS and utm_source in config.UTM_LINKS %}
#utm_container
a(href="{{config.UTM_LINKS[utm_source]['link']}}")
img(src="{{config.UTM_LINKS[utm_source]['image']}}", alt="gift", class="img-responsive")
| {% endif %}
#project_context
| {% block project_context %}
| {% if show_project %}
| {% include "projects/view_embed.html" %}
| {% endif %}
| {% endblock project_context %}
#overlay-mode-move-container
.overlay-container
.title
i.pi-angle-left
| Select the <strong>folder</strong> where you want to move it
.buttons
button#item_move_accept.move.disabled
| Select a Folder
button#item_move_cancel.cancel
i.pi-cancel
| Cancel
.p-5.text-center
h2 Project View
.lead.
See Blender Cloud for reference.
| {% endblock %}
| {% block footer_navigation %}{% endblock %}
| {% block footer %}{% endblock %}
| {% block footer_scripts_pre %}
| {% if project.has_method('PUT') %}
| {# JS containing the Edit, Add, Featured, and Move functions #}
script(type="text/javascript", src="{{ url_for('static_pillar', filename='assets/js/project-edit.min.js') }}")
| {% endif %}
script.
function updateToggleProjHeaderMenuItem() {
var $toggle_projheader = $('#item_toggle_projheader');
if (ProjectUtils.isProject()) {
$toggle_projheader.hide();
return;
}
if (ProjectUtils.nodeType() == 'asset') {
$toggle_projheader.show();
} else {
$toggle_projheader.hide();
}
}
$(updateToggleProjHeaderMenuItem);
// Function to update the interface on loadNodeContent, and edit/saving assets
function updateUi(nodeId, mode) {
if (mode === 'view') {
$('.project-mode-view').show();
$('.project-mode-edit').hide();
$("#node-edit-form").unbind("submit");
$("#item_save").unbind("click");
$("#item_cancel").unbind("click");
} else if (mode === 'edit') {
$('.project-mode-view').hide();
$('.project-mode-edit').show();
} else {
if (console) console.log('Invalid mode:', mode);
}
// Prevent flicker by scrolling to top
$("#project_context-container").scrollTop(0);
// Enable specific items under the Add New dropdown
if (ProjectUtils.nodeType() === 'group') {
addMenuEnable(['asset', 'group']);
} else if (ProjectUtils.nodeType() === 'group_texture') {
addMenuEnable(['group_texture', 'texture']);
} else if (ProjectUtils.nodeType() === 'group_hdri') {
addMenuEnable(['group_hdri', 'hdri']);
} else if (!ProjectUtils.isProject()) {
addMenuEnable(false);
}
updateToggleProjHeaderMenuItem();
// Set the page title on the document
var page_title = $('#node-title').text() + " - {{ project.name }} — Blender Cloud";
DocumentTitleAPI.set_page_title(page_title);
// TODO: Maybe remove this, now it's also in loadNodeContent(), but double-check
// it's done like that in all users of updateUi().
$('#project-loading').removeAttr('class');
}
| {% endblock %}
| {% block footer_scripts %}
script(src="{{ url_for('static_pillar', filename='assets/jstree/jstree.min.js') }}")
script.
{% if show_project %}
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: true, nodeId: ''});
{% else %}
{% if node %}
ProjectUtils.setProjectAttributes({projectId: "{{project._id}}", isProject: false, nodeId: '{{node._id}}'});
{% endif %}
{% endif %}
var projectTree = document.getElementById('project_tree');
var urlNodeMove = "{{url_for('projects.move_node')}}";
var urlNodeFeature = "{{url_for('projects.add_featured_node')}}";
var urlNodeDelete = "{{url_for('projects.delete_node')}}";
var urlNodeTogglePublic = "{{url_for('projects.toggle_node_public')}}";
var urlNodeToggleProjHeader = "{{url_for('projects.toggle_node_project_header')}}";
var urlProjectDelete = "{{url_for('projects.delete')}}";
var urlProjectEdit = "{{url_for('projects.edit', project_url=project.url)}}";
function loadNodeContent(url, nodeId) {
$('#project-loading').addClass('active');
$.get(url, function(dataHtml) {
// Update the DOM injecting the generate HTML into the page
$('#project_context').html(dataHtml);
})
.done(function(){
updateUi(nodeId, 'view');
})
.fail(function(dataResponse) {
$('#project_context').html($('<iframe id="server_error"/>'));
$('#server_error').attr('src', url);
})
.always(function(){
$('#project-loading').removeAttr('class');
$('.button-edit-icon').addClass('pi-edit').removeClass('pi-spin spin');
});
}
function loadProjectContent(url) {
$('#project-loading').addClass('active');
$.get(url, function(dataHtml) {
// Update the DOM injecting the generated HTML into the page
$('#project_context').html(dataHtml);
})
.done(function() {
updateUi('', 'view');
addMenuEnable();
addMenuDisable(['texture']);
})
.fail(function(dataResponse) {
$('#project_context').html($('<iframe id="server_error"/>'));
$('#server_error').attr('src', url);
})
.always(function(){
$('#project-loading').removeAttr('class');
$('.button-edit-icon').addClass('pi-edit').removeClass('pi-spin spin');
});
}
function displayStorage(storageNodeId, path) {
var url = '/nodes/' + storageNodeId + '/view?path=' + path;
loadNodeContent(url);
}
function displayNode(nodeId, pushState) {
// Remove the 'n_' suffix from the id
if (nodeId.substring(0, 2) == 'n_') {
nodeId = nodeId.substr(2);
}
var url = '/nodes/' + nodeId + '/view';
loadNodeContent(url, nodeId);
// Determine whether we should push the new state or not.
pushState = (typeof pushState !== 'undefined') ? pushState : true;
if (!pushState) return;
// Push the correct URL onto the history.
var push_state = {nodeId: nodeId, url: url};
var push_url = '{{url_for("projects.view", project_url=project.url)}}' + nodeId;
// console.log('Pushing state ', push_state, ' with URL ', push_url);
window.history.pushState(
push_state,
'Node ' + nodeId, // TODO: use sensible title
push_url
);
}
function redirectToNode(nodeId) {
var generic_url = '{{ url_for("projects.view_node", project_url=project.url, node_id="theNodeId") }}';
var node_url = generic_url.replace('theNodeId', nodeId);
// This makes the user skip the current page when using the 'back' button,
// i.e. it works as a proper redirect.
location.replace(node_url);
}
window.onpopstate = function(event) {
var state = event.state;
// console.log('State popped. location:', document.location, 'state:', state);
// Deselect any selected node. We'll select the visited node (if any) later on.
var jstreeAPI = $(projectTree).jstree(true);
jstreeAPI.deselect_all(true);
if (state == null) {
// Went back to the project.
displayProject();
return;
}
// Went back to a node.
loadNodeContent(state.url, state.nodeId);
// Annoying hack because jstreeAPI.select_node() can only suppress the
// changed.jstree event, and NOT the selected_node.jstree event.
projectTree.dataset.ignoreSelectNode = true;
jstreeAPI.select_node('n_' + state.nodeId, true);
delete projectTree.dataset.ignoreSelectNode;
};
function displayProject() {
var url = "{{url_for('projects.view', project_url=project.url, embed=1)}}";
loadProjectContent(url);
}
function getHashId() {
if (console)
console.log('getHashId() should not be used any more!');
}
/* Loaded once, on page load */
function loadContent() {
var nodeId = ProjectUtils.nodeId();
var isProject = ProjectUtils.isProject();
if (isProject) {
// No need to asynchronously load the project, as it's embedded by Jinja.
// displayProject() is still needed, though, when people use 'back' to go there.
if (location.hash) {
// Handle old-style /p/{url}/#node-ID links, and redirect them to the correct spot.
redirectToNode(location.hash.substr(1));
}
$('.project-mode-view').show();
$('.project-mode-edit').hide();
} else {
displayNode(nodeId, false);
}
$(projectTree).jstree({
'core': {
'data': function (obj, callback) {
if(obj.id === '#') { //tree root
if (isProject) {
$.getJSON("{{url_for('projects.jstree', project_url=project.url)}}", function (jsonObject) {
callback.call(this, jsonObject['items']);
});
} else {
$.getJSON('/nodes/' + nodeId + '/jstree', function(jsonObject) {
callback.call(this, jsonObject['items']);
});
}
} else { //normal node
var childNodeId;
if (obj.original.type == 'group_storage') {
childNodeId = obj.original.storage_node;
$.getJSON('/nodes/' + childNodeId + '/jstree?children=1&path=' + obj.original.path, function(jsonObject) {
callback.call(this, jsonObject.children);
});
} else {
// Remove the 'n_' suffix from the id
childNodeId = obj.id.substring(2);
$.getJSON('/nodes/' + childNodeId + '/jstree?children=1', function(jsonObject) {
callback.call(this, jsonObject.children);
});
}
}
}
},
"types" : {
"#": {"valid_children": ["collection"]},
"chapter" : {"icon": "pi-folder"},
"group" : {"icon": "pi-folder"},
"group_texture" : {"icon": "pi-folder-texture"},
"group_hdri" : {"icon": "pi-folder-texture", "max_children": 0},
"group_storage" : {"icon": "pi-folder"},
"filesystem_node" : {"icon": "pi-folder"},
"file" : {"icon": "pi-file-archive", "max_children": 0},
"filesystem_file" : {"icon": "pi-document", "max_children": 0},
"image" : {"icon": "pi-image", "max_children": 0},
"hdri" : {"icon": "pi-globe", "max_children": 0},
"texture" : {"icon": "pi-texture", "max_children": 0},
"video" : {"icon": "pi-film-thick", "max_children": 0},
"blog" : {"icon": "pi-newspaper", "max_children": 0},
"page" : {"icon": "pi-document-text", "max_children": 0},
"default" : {"icon": "pi-document"}
},
"plugins": ["types",] //, "state", "sort"
});
var jstreeAPI = $(projectTree).jstree(true);
$(projectTree).on("select_node.jstree", function (e, data) {
var selectedNodeId = data.node.id.substr(2);
// Ignore events that can't be suppressed otherwise.
// This can be removed if jstreeAPI.select_node() allows suppressing
// the select_node.jstree event.
if (e.target.dataset.ignoreSelectNode === 'true') return;
if (typeof(data.node.original.path) === 'undefined') {
var movingMode = Cookies.getJSON('bcloud_moving_node');
// Check if we are in the process of moving a node
if (movingMode) {
// Allow moving nodes only inside of node_type group
if (data.node.original.type != 'group' || movingMode.node_id === selectedNodeId || movingMode.node_id === ProjectUtils.parentNodeId()) {
if (movingMode.node_type === 'texture') {
if (data.node.original.type === 'group_texture') {
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
} else {
$('#item_move_accept').html('Select a Texture Folder').addClass('disabled');
}
} else if (movingMode.node_type === 'hdri') {
if (data.node.original.type === 'group_hdri') {
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
} else {
$('#item_move_accept').html('Select an HDRi Folder').addClass('disabled');
}
} else {
$('#item_move_accept').html('Select a Folder').addClass('disabled');
}
} else {
$('#item_move_accept').html('<i class="pi-check"></i>Move Here').removeClass('disabled');
}
}
// Check the type of node and act accordingly
if (data.node.original.custom_view) {
window.location = data.node.a_attr.href;
} else {
var currentNodeId = ProjectUtils.nodeId();
if (currentNodeId != selectedNodeId) {
displayNode(selectedNodeId);
}
jstreeAPI.open_node(data.node);
}
} else {
displayStorage(data.node.original.storage_node, data.node.original.path);
jstreeAPI.toggle_node(data.node);
}
});
};
{% if is_embedded_edit is not defined or is_embedded_edit %}
// Initialize the page if we are not directly editing a node (most of the time)
loadContent();
{% endif %}
var project_container = document.getElementById('project-container');
/* UI Stuff */
$(window).on("load resize",function(){
containerResizeY($(window).height());
if ($(window).width() > 480) {
project_container.style.height = (window.innerHeight - project_container.offsetTop) + "px";
}
});
{% if current_user_is_subscriber %}
$(projectTree).addClass('is_subscriber');
{% endif %}
| {% endblock %}
| {% block comment_scripts %} {% endblock%}

View File

@@ -22,9 +22,8 @@
| {% endif %}
section.node-details-container.project
.node-details-title
h1
a(href="{{ url_for( 'projects.view', project_url=project.url) }}") {{ project.name }}
h2.px-3.pt-3
a.text-muted(href="{{ url_for( 'projects.view', project_url=project.url) }}") {{ project.name }}
| {% if project.description %}
.node-details-description
@@ -127,5 +126,4 @@ script.
});
});
| {% endblock %}

View File

@@ -49,7 +49,7 @@
h3.
Now only &dollar;10 per month
.btn.btn-default
.btn.btn-outline-primary
| Join the Cloud
hr

View File

@@ -72,9 +72,9 @@
| none
| {% endif %}
a.btn.btn-default(href="javascript:update_from_bid()") Update from Blender ID
a.btn.btn-outline-secondary(href="javascript:update_from_bid()") Update from Blender ID
input#submit_edit_user.btn.btn-default(
input#submit_edit_user.btn.btn-outline-success(
data-user-id="{{user.user_id}}",
type="submit" value="Submit")

View File

@@ -18,11 +18,11 @@
.buttons
.login-button-container
//a.forgot(href="https://blender.org/id/reset") forgot your password?
button.btn.btn-success.btn-block.button-login(type="submit")
button.btn.btn-outline-success.btn-block.button-login(type="submit")
i.pi-log-in
| Login
//a.btn.btn-default.button-register(href="https://blender.org/id/register", target="_blank")
//a.btn.btn-outline-secondary.button-register(href="https://blender.org/id/register", target="_blank")
// i.pi-star-outline
// | Create Account

View File

@@ -3,7 +3,7 @@
//- can provide overrides.
| {% block body %}
.container
#settings
#settings.d-flex.py-4.flex-xs-column
#settings-sidebar
| {% block settings_sidebar %}
.settings-header

View File

@@ -28,7 +28,7 @@
span {{ _("Change Gravatar") }}
.buttons
button.btn.btn-default.button-submit(type='submit')
button.btn.btn-outline-success.button-submit(type='submit')
i.pi-check
| {{ _("Save Changes") }}
| {% endblock %}

View File

@@ -137,7 +137,7 @@ script().
$('td', row).eq(4).html(render_timing(data.timing));
$('td', row).eq(5).html(render_status_label(data, data.name));
var view_tag = '<span class="btn btn-default btn-xs load-shot-view" shot-view-url="' + data.url_edit + '"><i class="glyphicon glyphicon-edit"></i> View</span>';
var view_tag = '<span class="btn btn-outline-secondary btn-xs load-shot-view" shot-view-url="' + data.url_edit + '"><i class="glyphicon glyphicon-edit"></i> View</span>';
$('td', row).eq(6).html(view_tag);
}
});