notebook/app/views/basil/content.html.erb
Andrew Brown 11136b9115 Revert "Start free Basil month"
This reverts commit b0a2e1e2e9.
2025-06-30 23:10:14 -07:00

329 lines
16 KiB
Plaintext

<script type="text/javascript">
function commission_basil(style) {
// Set style hidden value to our selected style
$('#basil_commission_style').val(style);
// Submit form to start the commission
$('#new_basil_commission').submit();
}
</script>
<div class="row">
<%= form_for BasilCommission.new, url: basil_commission_path(@content_type, @content.id) do |f| %>
<%= f.hidden_field :style, value: 'realistic' %>
<%= f.hidden_field :entity_type, value: @content.page_type %>
<%= f.hidden_field :entity_id, value: @content.id %>
<div class="col s12 m4">
<div class="card-panel" style="padding: 1rem;">
<div style="margin: 1em 0; margin-bottom: 1rem;">
<%= link_to basil_path, class: 'grey-text text-darken-2' do %>
Basil
<% end %>
<i class="material-icons grey-text" style="display:inline-flex; vertical-align:top;">chevron_right</i>
<%= link_to basil_content_index_path(content_type: @content.page_type), class: 'grey-text text-darken-2' do %>
<%= @content.page_type.pluralize %>
<% end %>
</div>
<div class="clearfix">
<%= image_tag @content.random_image_including_private(format: :medium), style: 'width: 100%' %>
<h1 style="font-size: 2rem; margin-bottom: 0">
<%= link_to @content.name, @content.view_path, class: @content.text_color %>
</h1>
<%= link_to @content.edit_path, class: 'grey-text text-darken-2', style: 'margin-bottom: 1rem; display: inline-block;' do %>
Edit this <%= @content.page_type.downcase %>
<% end %>
</div>
<ul>
<% @relevant_fields.each do |field, value| %>
<%= f.hidden_field "field[#{field.id}][label]", value: field.label %>
<%= f.hidden_field "field[#{field.id}][value]", value: value %>
<li style="margin-bottom: 1em">
<div style="margin-bottom: 1rem; padding-bottom: 1rem;">
<div class="grey-text text-darken-1" style="font-weight: bold; font-size: 0.8em">
<div style="display: flex; align-items: center;">
<span style="position: relative; top: 0px; padding-right: 0.5rem; flex-grow: 1;"><%= field.label %></span>
<%= range_field_tag "basil_commission[field][#{field.id}][importance]", @guidance.fetch(field.id.to_s, 1), { min: 0, max: 1.3, step: 0.1, style: 'width: 60%;', class: 'js-importance-slider hide' } %>
</div>
</div>
<div style="margin-top: 0.5rem;">
<%= value %>
</div>
</div>
</li>
<% end %>
</ul>
<% if @relevant_fields.empty? %>
<div class="red card-panel lighten-3">
<strong>Basil works best with guidance!</strong>
<br /><br />
Please <%= link_to 'fill out more fields', @content.edit_path %> for this page
before requesting an image.
</div>
<% end %>
<div>
<% if @can_request_another && @relevant_fields.any? %>
<a href="javascript:var sliders = document.getElementsByClassName('js-importance-slider'); for(var i = 0; i < sliders.length; i++) sliders.item(i).classList.remove('hide'); document.getElementById('importance-explainer').classList.remove('hide');" class="waves-effect waves-light btn-small purple lighten-1" style="margin-bottom: 1rem;">Customize importance</a>
<% end %>
<div id="importance-explainer" class="js-importance-slider hide grey lighten-5" style="margin-right: 1em; padding: 1rem;">
<strong>How to customize per-field importance</strong>
<br /><br />
Customizing importance allows you to tell Basil which fields are more or less important to you. For example, if Basil is
focusing too hard on something specific you've said, you can turn down the importance of that field with
the slider.
<br /><br />
You can also tell Basil to ignore your answer to a field entirely by dragging the slider all the way to the left.
<br /><br />
Your preferences for this page are saved whenever you request an image and will be used for all future images for your <%= @content_type.downcase.pluralize %>.
</div>
</div>
<!--
<div style="margin-top: 2rem">
<%= link_to new_polymorphic_path(@content.page_type.downcase), class: "hoverable card-panel white-text #{@content.color}", style: 'display: block' do %>
<i class="material-icons left">add</i>
<span>
Create another <%= @content.page_type.downcase %>
</span>
<% end %>
</div>
-->
</div>
<div style="margin-top: 1.5rem; margin-bottom: 1rem;">
<% unless current_user.on_premium_plan? %>
<div class="orange lighten-2 card-panel">
<strong>
Image generation is a Premium-only feature, but free accounts can still generate up
to <%= pluralize BasilService::FREE_IMAGE_LIMIT, 'image' %> for free.
</strong>
<br /><br />
You have generated <%= pluralize @generated_images_count, 'image' %>
and have <%= pluralize [0, BasilService::FREE_IMAGE_LIMIT - @generated_images_count].max, 'free image' %> remaining:
<div class="progress white">
<div class="determinate blue" style="width: <%= [@generated_images_count, BasilService::FREE_IMAGE_LIMIT].min %>%"></div>
</div>
<% if @generated_images_count >= BasilService::FREE_IMAGE_LIMIT %>
<%= link_to 'Click here to manage your billing plan', subscription_path, class: 'blue-text text-darken-4' %>
<% end %>
</div>
<% end %>
</div>
</div>
<% end %>
<div class="col s12 m8" style="margin-top: 1rem">
<%= render partial: 'notice_dismissal/messages/19' if show_notice?(id: 19) %>
<% if @can_request_another && @relevant_fields.any? %>
<div class="row" style="padding-left: 0.5rem">
<div class="grey-text center" style="font-size: 1.2rem; margin-bottom: 0.5rem;"><strong>Image Styles</strong></div>
<% BasilService.enabled_styles_for(@content.page_type).each do |style| %>
<div class="col s12 m6 l4">
<%= link_to "javascript:commission_basil('#{style}')",
class: "waves-effect waves-light purple lighten-1 white-text hoverable",
style: "display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; min-height: 120px; text-align: center; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; box-shadow: 0 2px 5px rgba(0,0,0,0.1); text-decoration: none; transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;" do %>
<i class="material-icons" style="font-size: 2rem; margin-bottom: 0.5rem;">palette</i>
<span><%= style.humanize %></span>
<% end %>
</div>
<% end %>
<% BasilService.experimental_styles_for(@content.page_type).each do |style| %>
<div class="col s12 m6 l4">
<%= link_to "javascript:commission_basil('#{style}')",
class: "waves-effect waves-light purple lighten-3 white-text hoverable",
style: "display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; min-height: 120px; text-align: center; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; box-shadow: 0 2px 5px rgba(0,0,0,0.1); text-decoration: none; transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;" do %>
<i class="material-icons" style="font-size: 2rem; margin-bottom: 0.5rem;">science</i>
<span><%= style.humanize %> (Experimental)</span>
<% end %>
</div>
<% end %>
<div class="grey-text center col s12"><strong>Click a style to generate an image in that style</strong></div>
</div>
<% end %>
<% if !@can_request_another && @in_progress_commissions.any? %>
<div class="card-panel blue lighten-5" style="padding: 1.5rem; display: flex; align-items: center; border-left: 5px solid #1e88e5; /* Blue darken-1 */">
<i class="material-icons blue-text text-darken-2" style="font-size: 2.8rem; margin-right: 1.5rem;">hourglass_top</i>
<div>
<h6 class="blue-grey-text text-darken-3" style="font-weight: 500; margin-top: 0; margin-bottom: 0.35rem;">
Basil is currently working on <%= pluralize @in_progress_commissions.count, 'commission' %> for you.
</h6>
<p class="blue-grey-text text-darken-1" style="margin-bottom: 0; font-size: 0.95rem;">
As soon as one is complete, you'll be able to request another.
</p>
</div>
</div>
<% end %>
<div class="row" style="padding-left: 0.5rem">
<% @commissions.each do |commission| %>
<div class="col s12">
<div>
<% if commission.complete? %>
<div class="card">
<div class="card-image">
<%= link_to commission.image do %>
<%= image_tag commission.image %>
<% end %>
</div>
<div class="card-content" style="padding: 18px;">
<div>
<strong><%= @content.name %></strong>
<% if commission.style? %>
<em>(<%= commission.style.humanize %>)</em>
<% end %>
</div>
<div class="grey-text text-darken-2">
<span style="font-size: 0.8em">Completed <%= time_ago_in_words commission.completed_at %> ago</span>
&middot;<br />
<span style="font-size: 0.8em">Took <%= distance_of_time_in_words commission.completed_at - commission.created_at %></span>
</div>
<div style="margin-top: 1em">
<div class="center" style="font-size: 0.9em; margin-bottom: 0.5rem;"><strong>Feedback for Basil</strong></div>
<div class="row" style="margin-bottom: 0;">
<%= form_for commission.basil_feedbacks.find_or_initialize_by(user: current_user), url: basil_feedback_path(commission.job_id), method: :POST, remote: true do |f| %>
<div class="col s3 center-align" style="padding: 0 2px;">
<label>
<%= f.radio_button :score_adjustment, '-2', { class: 'autosave-closest-form-on-change' } %>
<span class="black-text"><i class="material-icons red-text text-darken-1">sentiment_very_dissatisfied</i></span>
</label>
</div>
<div class="col s2 center-align" style="padding: 0 2px;">
<label>
<%= f.radio_button :score_adjustment, '-1', { class: 'autosave-closest-form-on-change' } %>
<span class="black-text"><i class="material-icons orange-text">sentiment_dissatisfied</i></span>
</label>
</div>
<div class="col s2 center-align" style="padding: 0 2px;">
<label>
<%= f.radio_button :score_adjustment, '1', { class: 'autosave-closest-form-on-change' } %>
<span class="black-text"><i class="material-icons light-green-text">sentiment_satisfied</i></span>
</label>
</div>
<div class="col s2 center-align" style="padding: 0 2px;">
<label>
<%= f.radio_button :score_adjustment, '2', { class: 'autosave-closest-form-on-change' } %>
<span class="black-text"><i class="material-icons green-text text-darken-1">sentiment_very_satisfied</i></span>
</label>
</div>
<div class="col s3 center-align" style="padding: 0 2px;">
<label>
<%= f.radio_button :score_adjustment, '3', { class: 'autosave-closest-form-on-change' } %>
<span class="red-text text-darken-1"><i class="material-icons">favorite</i></span>
</label>
</div>
<% end %>
</div>
</div>
</div>
<div class="card-action">
<% if commission.saved_at? %>
<%= link_to 'Saved', commission.entity, class: 'blue-text' %>
<% else %>
<%= link_to "Save to page", '#', class: 'js-save-commission purple-text', data: { endpoint: basil_save_path(commission) } %>
<% end %>
<%= link_to "Delete", '#', class: 'js-delete-commission red-text right right-align', style: 'margin-right: 0', data: { endpoint: basil_delete_path(commission) } %>
</div>
</div>
<% else %>
<div class="card-panel orange lighten-5 basil-loading-card" style="display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; border: 1px dashed #a5d6a7; /* Light green for pulsing border */ min-height: 180px; position: relative; overflow: hidden;">
<div class="preloader-wrapper medium active">
<div class="spinner-layer spinner-blue-only">
<div class="circle-clipper left">
<div class="circle"></div>
</div><div class="gap-patch">
<div class="circle"></div>
</div><div class="circle-clipper right">
<div class="circle"></div>
</div>
</div>
</div>
<h5 style="color: #424242; font-weight: 600; margin-bottom: 0.5rem;">Working on it!</h5>
<p style="font-size: 1rem; color: #616161; margin-bottom: 0.75rem;">
Basil is crafting your image in the <strong><%= commission.style.try(:humanize) || 'selected' %></strong> style.
</p>
<p style="font-size: 0.9em; color: #757575;">
Requested <%= time_ago_in_words(commission.created_at) %> ago. <br class="hide-on-med-and-up">Please refresh for updates.
</p>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
<% if @commissions.count == 10 %>
<div class="card-panel">
<div><strong>End of the list?</strong></div>
<p>
Only your 10 most recent generations are displayed here, but you can still find all
of your generated images on the <%= link_to 'Basil Feedback', basil_rating_queue_path %> pages.
</p>
</div>
<% end %>
</div>
</div>
<% content_for :javascript do %>
$(document).ready(function() {
$('.js-save-commission').click(function(e) {
$(this).text('Saved!');
var save_endpoint = $(this).data('endpoint') + '.json';
$.post(save_endpoint, function(data) {
console.log(data);
M.toast({ html: "This image has been added to <%= @content.name.gsub('"', '\"') %>'s page." });
});
e.preventDefault();
});
$('.js-delete-commission').click(function(e) {
$(this).text('Deleting...');
$(this).closest('.card').hide();
var delete_endpoint = $(this).data('endpoint') + '.json';
$.ajax({
url: delete_endpoint,
type: 'DELETE',
success: function(result) {
$(this).closest('.card').hide();
M.toast({ html: "Image successfully deleted." });
}
});
e.preventDefault();
});
});
<% end %>
<% content_for :css_includes do %>
<style>
@keyframes pulse-border {
0% {
border-color: #a5d6a7; /* Light green */
box-shadow: 0 0 0 0 rgba(165, 214, 167, 0.4);
}
70% {
box-shadow: 0 0 0 10px rgba(165, 214, 167, 0);
}
100% {
border-color: #e8f5e9; /* Lighter green */
box-shadow: 0 0 0 0 rgba(165, 214, 167, 0);
}
}
.basil-loading-card {
animation: pulse-border 2s infinite;
}
</style>
<% end %>