lab
This commit is contained in:
parent
7cd9c68a10
commit
36984ff1d4
20 changed files with 321 additions and 391 deletions
|
|
@ -14,12 +14,14 @@
|
|||
// window.$ = window.jQuery = jQuery; // Expose globally (if needed)
|
||||
|
||||
// import "./foundation-sites/dist/js/foundation.min";
|
||||
import "./controllers";
|
||||
import "@hotwired/turbo-rails";
|
||||
|
||||
|
||||
// import jquery from "jquery";
|
||||
import jQuery from "./jquery.js";
|
||||
|
||||
// window.jQuery = jquery;
|
||||
// window.$ = jquery;
|
||||
window.$ = jQuery;
|
||||
|
||||
$(function () {
|
||||
$(document).foundation();
|
||||
|
|
@ -43,89 +45,3 @@ $(function () {
|
|||
// );
|
||||
// };
|
||||
|
||||
// Initialize the upload form.
|
||||
function upload_form_init() {
|
||||
// Disable the submit button if Javascript is supported.
|
||||
// Upload will start right after selecting images.
|
||||
$('#file-submit').hide();
|
||||
|
||||
// Install event handler to notice when files were selected.
|
||||
$('#file').on('change', upload_form_files_selected);
|
||||
};
|
||||
|
||||
function upload_form_files_selected() {
|
||||
no_files = this.files.length;
|
||||
if (no_files > 0) {
|
||||
$('#file-label').html(no_files+" files selected - uploading…"); // change label
|
||||
$('#file-select-button').attr('disabled','disabled'); // disable select button
|
||||
$('#file-form').trigger('submit'); // start upload
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Handle Ctrl-V to paste an image directly
|
||||
function upload_paste_handler(event)
|
||||
{
|
||||
console.log("paste!");
|
||||
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||
|
||||
// /*Make Sure Only One File is Copied*/
|
||||
// if (items.length != 1) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
for (var i = 0 ; i < items.length ; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
console.log(item);
|
||||
console.log("item size="+item.size);
|
||||
if (!item.type.startsWith('image/'))
|
||||
{
|
||||
console.log("Skipping file with type "+item.type);
|
||||
continue
|
||||
}
|
||||
console.log(item.type);
|
||||
var file = item.getAsFile();
|
||||
console.log(file);
|
||||
upload_file_with_ajax(file);
|
||||
}
|
||||
}
|
||||
|
||||
function upload_file_with_ajax(file)
|
||||
{
|
||||
if (file==null)
|
||||
{
|
||||
console.log("File was null. Strange.");
|
||||
display_error('Maybe the image was too large.');
|
||||
return;
|
||||
}
|
||||
var formData = new FormData();
|
||||
formData.append('file', file);
|
||||
|
||||
$.ajax(ajax_upload_url,
|
||||
{
|
||||
type: 'POST',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
data: formData,
|
||||
//dataType: 'json',
|
||||
error: function(xhr, txt, err)
|
||||
{
|
||||
console.log("AJAX file upload returned error: "+txt+" / "+err);
|
||||
response = JSON.parse(xhr.responseText);
|
||||
display_error(response);
|
||||
},
|
||||
success: function(res)
|
||||
{
|
||||
console.log("AJAX file upload was ok");
|
||||
// Go back to details page to show the new upload
|
||||
window.location.replace(after_upload_url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function display_error(msg)
|
||||
{
|
||||
$('#messages').html(
|
||||
'<div class="callout alert alert-callout-subtle radius">Sorry, pasting did not work. ' + msg + '</div>')
|
||||
}
|
||||
|
|
|
|||
2
app/assets/javascripts/foundation.js
vendored
Normal file
2
app/assets/javascripts/foundation.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
app/assets/javascripts/jquery.js
vendored
Normal file
2
app/assets/javascripts/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
app/assets/stylesheets/foundation.css
vendored
Normal file
2
app/assets/stylesheets/foundation.css
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -4,15 +4,15 @@ class WelcomeController < ApplicationController
|
|||
def home
|
||||
@newest_upload = Screenshot.where(approved: true).first
|
||||
|
||||
#@most_popular_package = Package.with_screenshots.order(visits: :desc).first
|
||||
@random_pick = Package.with_public_screenshots.order("RANDOM()").first
|
||||
# @most_popular_package = Package.with_screenshots.order(visits: :desc).first
|
||||
@random_pick = Package.with_public_screenshots.order('RANDOM()').first
|
||||
|
||||
@package_count = Package.count
|
||||
|
||||
# Get up 100 screenshots where the packages have the most visits
|
||||
query = Package.without_screenshots #.order(visits: :desc)
|
||||
query = Package.without_screenshots # .order(visits: :desc)
|
||||
count = query.count
|
||||
random_offset = rand( [100, count].min )
|
||||
random_offset = rand([100, count].min)
|
||||
@most_wanted_package = query.offset(random_offset).first
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,62 +1,34 @@
|
|||
// Entry point for the build script in your package.json
|
||||
// import "@hotwired/turbo-rails";
|
||||
// import "jquery";
|
||||
import "foundation-sites";
|
||||
// import 'foundation-sites/dist/css/foundation.min.css'; // CSS
|
||||
import "./controllers";
|
||||
|
||||
// // Entry point for the build script in your package.json
|
||||
|
||||
import jquery from "jquery";
|
||||
|
||||
window.jQuery = jquery;
|
||||
window.$ = jquery;
|
||||
|
||||
$(function () {
|
||||
$(document).foundation();
|
||||
});
|
||||
|
||||
// Load reviews on package's details page
|
||||
// load_reviews = function() {
|
||||
// // Display message while loading reviews
|
||||
// // $('#reviews').html("<i>Loading reviews...</i>");
|
||||
|
||||
// // Hide the DIV so that in can be faded in later
|
||||
// $('#reviews').hide();
|
||||
|
||||
// // The URL is specified in the #reviews's DIV data attribute
|
||||
// var url = $('#reviews').attr('data-package-reviews-url');
|
||||
// $('#reviews').load(url, null,
|
||||
// // Fade in the reviews as soon as the DIV is loaded and filled
|
||||
// function(){
|
||||
// $(this).fadeIn('slow')
|
||||
// }
|
||||
// );
|
||||
// };
|
||||
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
|
||||
import "@hotwired/turbo-rails"
|
||||
import "controllers"
|
||||
|
||||
// Initialize the upload form.
|
||||
function upload_form_init() {
|
||||
// Disable the submit button if Javascript is supported.
|
||||
// Upload will start right after selecting images.
|
||||
$('#file-submit').hide();
|
||||
// $("#file-submit").hide();
|
||||
document.getElementById("file-submit").style.display = "none";
|
||||
|
||||
// Install event handler to notice when files were selected.
|
||||
$('#file').on('change', upload_form_files_selected);
|
||||
};
|
||||
// $("#file").on("change", upload_form_files_selected);
|
||||
document.getElementById("file").addEventListener("change", upload_form_files_selected);
|
||||
}
|
||||
|
||||
function upload_form_files_selected() {
|
||||
no_files = this.files.length;
|
||||
if (no_files > 0) {
|
||||
$('#file-label').html(no_files+" files selected - uploading…"); // change label
|
||||
$('#file-select-button').attr('disabled','disabled'); // disable select button
|
||||
$('#file-form').trigger('submit'); // start upload
|
||||
}
|
||||
};
|
||||
document.getElementById("file-label").innerHTML = `${no_files} files selected - uploading…`;
|
||||
document.getElementById("file-select-button").disabled = true;
|
||||
document.getElementById("file-form").submit();
|
||||
|
||||
// $("#file-label").html(no_files + " files selected - uploading…"); // change label
|
||||
// $("#file-select-button").attr("disabled", "disabled"); // disable select button
|
||||
// $("#file-form").trigger("submit"); // start upload
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Ctrl-V to paste an image directly
|
||||
function upload_paste_handler(event)
|
||||
{
|
||||
export function upload_paste_handler(event) {
|
||||
console.log("paste!");
|
||||
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||
|
||||
|
|
@ -65,15 +37,13 @@ function upload_paste_handler(event)
|
|||
// return;
|
||||
// }
|
||||
|
||||
for (var i = 0 ; i < items.length ; i++)
|
||||
{
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
console.log(item);
|
||||
console.log("item size="+item.size);
|
||||
if (!item.type.startsWith('image/'))
|
||||
{
|
||||
console.log("Skipping file with type "+item.type);
|
||||
continue
|
||||
console.log("item size=" + item.size);
|
||||
if (!item.type.startsWith("image/")) {
|
||||
console.log("Skipping file with type " + item.type);
|
||||
continue;
|
||||
}
|
||||
console.log(item.type);
|
||||
var file = item.getAsFile();
|
||||
|
|
@ -82,41 +52,68 @@ function upload_paste_handler(event)
|
|||
}
|
||||
}
|
||||
|
||||
function upload_file_with_ajax(file)
|
||||
{
|
||||
if (file==null)
|
||||
{
|
||||
function upload_file_with_ajax(file) {
|
||||
if (file == null) {
|
||||
console.log("File was null. Strange.");
|
||||
display_error('Maybe the image was too large.');
|
||||
display_error("Maybe the image was too large.");
|
||||
return;
|
||||
}
|
||||
var formData = new FormData();
|
||||
formData.append('file', file);
|
||||
formData.append("file", file);
|
||||
|
||||
$.ajax(ajax_upload_url,
|
||||
{
|
||||
type: 'POST',
|
||||
contentType: false,
|
||||
processData: false,
|
||||
data: formData,
|
||||
//dataType: 'json',
|
||||
error: function(xhr, txt, err)
|
||||
{
|
||||
console.log("AJAX file upload returned error: "+txt+" / "+err);
|
||||
response = JSON.parse(xhr.responseText);
|
||||
display_error(response);
|
||||
fetch(ajax_upload_url, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: {
|
||||
// 'Content-Type' is omitted to let the browser set it automatically
|
||||
// with the proper boundary for FormData
|
||||
},
|
||||
success: function(res)
|
||||
{
|
||||
console.log("AJAX file upload was ok");
|
||||
// Go back to details page to show the new upload
|
||||
window.location.replace(after_upload_url);
|
||||
})
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json();
|
||||
console.log(`AJAX file upload returned error: ${response.statusText}`);
|
||||
display_error(errorData);
|
||||
throw new Error("Upload failed");
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then((data) => {
|
||||
console.log("AJAX file upload was ok");
|
||||
window.location.replace(after_upload_url);
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.message !== "Upload failed") {
|
||||
console.log(`AJAX file upload error: ${error}`);
|
||||
}
|
||||
});
|
||||
|
||||
// $.ajax(ajax_upload_url, {
|
||||
// type: "POST",
|
||||
// contentType: false,
|
||||
// processData: false,
|
||||
// data: formData,
|
||||
// //dataType: 'json',
|
||||
// error: function (xhr, txt, err) {
|
||||
// console.log("AJAX file upload returned error: " + txt + " / " + err);
|
||||
// response = JSON.parse(xhr.responseText);
|
||||
// display_error(response);
|
||||
// },
|
||||
// success: function (res) {
|
||||
// console.log("AJAX file upload was ok");
|
||||
// // Go back to details page to show the new upload
|
||||
// window.location.replace(after_upload_url);
|
||||
// },
|
||||
// });
|
||||
}
|
||||
|
||||
function display_error(msg)
|
||||
{
|
||||
$('#messages').html(
|
||||
'<div class="callout alert alert-callout-subtle radius">Sorry, pasting did not work. ' + msg + '</div>')
|
||||
function display_error(msg) {
|
||||
// $("#messages").html(
|
||||
// '<div class="callout alert alert-callout-subtle radius">Sorry, pasting did not work. ' + msg + "</div>"
|
||||
// );
|
||||
document.querySelector("#messages").innerHTML = `
|
||||
<div class="callout alert alert-callout-subtle radius">
|
||||
Sorry, pasting did not work. ${msg}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
// This file is auto-generated by ./bin/rails stimulus:manifest:update
|
||||
// Run that command whenever you add a new controller or create them with
|
||||
// ./bin/rails generate stimulus controllerName
|
||||
|
||||
import { application } from "./application"
|
||||
|
||||
import HelloController from "./hello_controller"
|
||||
application.register("hello", HelloController)
|
||||
// Import and register all your controllers from the importmap via controllers/**/*_controller
|
||||
import { application } from "controllers/application"
|
||||
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
|
||||
eagerLoadControllersFrom("controllers", application)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
require 'open-uri' # allows to load URLs using open()
|
||||
require 'open-uri' # allows to load URLs using open()
|
||||
require 'json'
|
||||
require 'deb_importer'
|
||||
|
||||
|
|
@ -8,26 +8,26 @@ class Package < ApplicationRecord
|
|||
include PgSearch::Model
|
||||
# TODO: Make search weighted on users' rating
|
||||
pg_search_scope :general_search,
|
||||
# :against => [:name, :description, :long_description],
|
||||
:against => [
|
||||
[:name, 'A'],
|
||||
[:description, 'B'],
|
||||
[:long_description, 'C']
|
||||
],
|
||||
:using => {
|
||||
:tsearch => {:dictionary => "english"}
|
||||
}
|
||||
# :against => [:name, :description, :long_description],
|
||||
against: [
|
||||
[:name, 'A'],
|
||||
[:description, 'B'],
|
||||
[:long_description, 'C']
|
||||
],
|
||||
using: {
|
||||
tsearch: { dictionary: 'english' }
|
||||
}
|
||||
|
||||
# I am using "destroy_all" here so that when a package gets destroys the
|
||||
# callbacks for all dependent screenshots are executed - thus removing the
|
||||
# screenshot files from disk.
|
||||
has_many :screenshots,
|
||||
-> { order(id: :desc) },
|
||||
:inverse_of=>:package,
|
||||
:dependent => :destroy
|
||||
-> { order(id: :desc) },
|
||||
inverse_of: :package,
|
||||
dependent: :destroy
|
||||
|
||||
# default_scope {
|
||||
# order('name ASC')
|
||||
# order('name ASC')
|
||||
# }
|
||||
|
||||
# Define the parameter(s) used for a /package/:name URL to an instance of this model
|
||||
|
|
@ -37,11 +37,7 @@ class Package < ApplicationRecord
|
|||
|
||||
# Return the first paragraph of the long description.
|
||||
def long_description_first_paragraph
|
||||
if self.long_description
|
||||
self.long_description.split(/\n\.\n/).first
|
||||
else
|
||||
nil
|
||||
end
|
||||
long_description.split(/\n\.\n/).first if long_description
|
||||
end
|
||||
|
||||
# Return a query of all packages that have screenshots
|
||||
|
|
@ -72,7 +68,7 @@ class Package < ApplicationRecord
|
|||
|
||||
# Get all screenshots and have them sorted descendingly by their version number (Debian style).
|
||||
def screenshots_sorted_by_version
|
||||
self.screenshots.approved.to_a.sort { |x,y| version_compare(x.version,y.version) }
|
||||
screenshots.approved.to_a.sort { |x, y| version_compare(x.version, y.version) }
|
||||
end
|
||||
|
||||
# Return the newest screenshot that is not newer than the given version.
|
||||
|
|
@ -83,29 +79,29 @@ class Package < ApplicationRecord
|
|||
# This way the user does not see a screenshot of version 2.0 because
|
||||
# 2.0 might contain features that were not there in version 1.5.
|
||||
def best_screenshot_for_version(version)
|
||||
sorted_screenshots = self.screenshots_sorted_by_version
|
||||
sorted_screenshots = screenshots_sorted_by_version
|
||||
sorted_screenshots.each do |ss|
|
||||
logger.debug { "Comparing version #{version} against #{ss.version}" }
|
||||
return ss if version_compare(version, ss.version)<=0
|
||||
return ss if version_compare(version, ss.version) <= 0
|
||||
end
|
||||
return sorted_screenshots.last
|
||||
sorted_screenshots.last
|
||||
end
|
||||
|
||||
# Return the part of the version up to the first - or +
|
||||
def upstream_version
|
||||
self.version.split(/[\-\+]/).first
|
||||
version.split(/[-+]/).first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def version_compare(x,y)
|
||||
def version_compare(x, y)
|
||||
x = '0' unless x.present?
|
||||
y = '0' unless y.present?
|
||||
version_x = DebImporter::Version.new(x)
|
||||
version_y = DebImporter::Version.new(y)
|
||||
if version_x<version_y
|
||||
if version_x < version_y
|
||||
1
|
||||
elsif version_x>version_y
|
||||
elsif version_x > version_y
|
||||
-1
|
||||
else
|
||||
0
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class Screenshot < ApplicationRecord
|
|||
|
||||
scope :approved, -> { where(approved: true) }
|
||||
scope :visible, -> { where(hidden: false) }
|
||||
scope :publicly, -> { where(hidden: false, approved: true) }
|
||||
|
||||
# Shrine
|
||||
include ImageUploader::Attachment(:simage) # adds an `simage` virtual attribute
|
||||
|
|
@ -17,10 +18,10 @@ class Screenshot < ApplicationRecord
|
|||
# Takes the description of a screenshot if available.
|
||||
# Otherwise it falls back to the general description of its package.
|
||||
def caption
|
||||
if self.description.present?
|
||||
"#{self.description}"
|
||||
if description.present?
|
||||
"#{description}"
|
||||
else
|
||||
"#{self.package.description}"
|
||||
"#{package.description}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -37,25 +38,23 @@ class Screenshot < ApplicationRecord
|
|||
def status
|
||||
text = 'This image '
|
||||
|
||||
if self.approved
|
||||
text << 'is public'
|
||||
else
|
||||
text << 'has to be moderated before being publicly visible'
|
||||
end
|
||||
text << if approved
|
||||
'is public'
|
||||
else
|
||||
'has to be moderated before being publicly visible'
|
||||
end
|
||||
|
||||
if self.markedfordelete
|
||||
text << ' (and was requested to be removed)'
|
||||
end
|
||||
text << ' (and was requested to be removed)' if markedfordelete
|
||||
|
||||
return text
|
||||
text
|
||||
end
|
||||
|
||||
# Brief text describing the status of this screenshots (for admins)
|
||||
def adminstatus
|
||||
if self.approved
|
||||
if approved
|
||||
'Public'
|
||||
else
|
||||
#fa_icon('hourglass') + 'Waiting for approval'
|
||||
# fa_icon('hourglass') + 'Waiting for approval'
|
||||
'Unapproved'
|
||||
end
|
||||
end
|
||||
|
|
@ -63,32 +62,33 @@ class Screenshot < ApplicationRecord
|
|||
# Publish a screenshot from the moderation queue
|
||||
def approve!
|
||||
self.approved = true
|
||||
self.save!
|
||||
save!
|
||||
end
|
||||
|
||||
# Hide a screenshot from the public. Moderator level can do this.
|
||||
def hide!
|
||||
self.hidden = true
|
||||
self.save!
|
||||
save!
|
||||
end
|
||||
|
||||
def unhide!
|
||||
self.hidden = false
|
||||
self.save!
|
||||
save!
|
||||
end
|
||||
|
||||
# Get the newest screenshots regardless of the package it belongs to
|
||||
def self.newest
|
||||
self.order(created_at: :desc)
|
||||
order(created_at: :desc)
|
||||
end
|
||||
|
||||
# Return the part of the version up to the first - or +
|
||||
def upstream_version
|
||||
self.version.split(/[\-\+]/).first
|
||||
version.split(/[-+]/).first
|
||||
end
|
||||
|
||||
# Returns the path to this screenshot's image on disk
|
||||
def disk_path
|
||||
ActiveStorage::Blob.service.send(:path_for, self.image.key)
|
||||
ActiveStorage::Blob.service.send(:path_for, image.key)
|
||||
end
|
||||
|
||||
# Returns the MD5 hex digest of the current screenshot's data
|
||||
|
|
@ -98,8 +98,8 @@ class Screenshot < ApplicationRecord
|
|||
Digest::MD5.hexdigest(disk_path)
|
||||
|
||||
# remote files stored on another person's computer:
|
||||
#url = attachment.url
|
||||
#Digest::MD5.base64digest(Net::HTTP.get(URI(url)))
|
||||
# url = attachment.url
|
||||
# Digest::MD5.base64digest(Net::HTTP.get(URI(url)))
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -112,11 +112,9 @@ class Screenshot < ApplicationRecord
|
|||
# for two different packages. Restricting that further may happen later.
|
||||
def validate_image_is_unique
|
||||
# Look for images with the same checksum / image_fingerprint
|
||||
if screenshot=Screenshot.find_by(image_fingerprint: image_fingerprint, package_id: self.package.id)
|
||||
unless screenshot.id == self.id
|
||||
errors.add(:image, "has already been uploaded for this package")
|
||||
end
|
||||
if (screenshot = Screenshot.find_by(image_fingerprint: image_fingerprint,
|
||||
package_id: package.id)) && !(screenshot.id == id)
|
||||
errors.add(:image, 'has already been uploaded for this package')
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,14 +12,13 @@ html
|
|||
/ = stylesheet_link_tag :app, "data-turbo-track": "reload"
|
||||
/ = javascript_include_tag "application", "data-turbo-track": "reload", type: "module"
|
||||
|
||||
/ = stylesheet_link_tag "foundation", media: "all"
|
||||
= stylesheet_link_tag "application", media: "all"
|
||||
/ = javascript_include_tag "jquery/dist/jquery.min.js"
|
||||
/ = javascript_include_tag "foundation-sites/dist/js/foundation.min"
|
||||
= javascript_include_tag "jquery-3.7.1.min.js", "data-turbo-track": "reload", type: "module"
|
||||
= javascript_include_tag "foundation", "data-turbo-track": "reload", type: "module"
|
||||
= javascript_include_tag "debshots", "data-turbo-track": "reload", type: "module"
|
||||
/ = javascript_include_tag "application", "data-turbo-track": "reload", type: "module"
|
||||
|
||||
/ = javascript_include_tag "jquery.js", "data-turbo-track": "reload", type: "module"
|
||||
/ = javascript_include_tag "foundation", "data-turbo-track": "reload", type: "module"
|
||||
/ = javascript_include_tag "debshots", "data-turbo-track": "reload", type: "module"
|
||||
|
||||
= javascript_importmap_tags
|
||||
|
||||
= csrf_meta_tags
|
||||
|
||||
|
|
|
|||
|
|
@ -23,5 +23,5 @@
|
|||
/ ' My uploads
|
||||
|
||||
li
|
||||
= link_to destroy_user_session_path, method: :delete
|
||||
= link_to destroy_user_session_path, data: { turbo_method: :delete }
|
||||
= fa_icon 'lock 2x', text: 'Logout'
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@
|
|||
= render(partial: 'details_rightbox', locals: {pkg: @package})
|
||||
|
||||
javascript:
|
||||
import {upload_paste_handler} from 'aplication';
|
||||
|
||||
// Handle Ctrl-V to paste an image directly
|
||||
document.onpaste = upload_paste_handler;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,16 +64,18 @@ h1 = "Upload screenshots for #{@package.name}"
|
|||
' from a shell using after setting "export LANG=C".
|
||||
li can be pasted here from your clipboard (Ctrl-V)
|
||||
|
||||
/ javascript:
|
||||
/ // Hide the submit button unless images are selected for upload
|
||||
/ // $(document).ready(upload_form_init);
|
||||
/ import upload_form_init from '../../assets/javascripts/upload.js';
|
||||
/ document.addEventListener('DOMContentLoaded', upload_form_init);
|
||||
|
||||
javascript:
|
||||
// Hide the submit button unless images are selected for upload
|
||||
$(document).ready(upload_form_init);
|
||||
/ // import upload_paste_handler from '../../assets/javascripts/debshots.js';
|
||||
/ // Handle Ctrl-V to paste an image directly
|
||||
/ document.onpaste = upload_paste_handler;
|
||||
|
||||
// Handle Ctrl-V to paste an image directly
|
||||
document.onpaste = upload_paste_handler;
|
||||
/ // Where to send POST requests for uploads
|
||||
/ var ajax_upload_url = '#{{upload_receive_json_path}}';
|
||||
|
||||
// Where to send POST requests for uploads
|
||||
var ajax_upload_url = '#{{upload_receive_json_path}}';
|
||||
|
||||
// Where to go to after a successful image upload
|
||||
var after_upload_url = '#{{package_path(@package)}}';
|
||||
/ // Where to go to after a successful image upload
|
||||
/ var after_upload_url = '#{{package_path(@package)}}';
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
.image
|
||||
- if @random_pick
|
||||
a href=package_path(@random_pick.name)
|
||||
= small_img(@random_pick.screenshots.first)
|
||||
= small_img(@random_pick.screenshots.publicly.first)
|
||||
- else
|
||||
'No uploaded screenshots yet.
|
||||
.text
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue