mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 21:16:22 +00:00
Merge branch 'rails' of 0xacab.org:sutty/sutty into rails
This commit is contained in:
commit
7d5a8f8d48
6 changed files with 161 additions and 4 deletions
|
@ -11,6 +11,7 @@ class ApplicationController < ActionController::Base
|
||||||
before_action :configure_permitted_parameters, if: :devise_controller?
|
before_action :configure_permitted_parameters, if: :devise_controller?
|
||||||
before_action :notify_unconfirmed_email, unless: :devise_controller?
|
before_action :notify_unconfirmed_email, unless: :devise_controller?
|
||||||
around_action :set_locale
|
around_action :set_locale
|
||||||
|
after_action :store_location!
|
||||||
|
|
||||||
rescue_from Pundit::NilPolicyError, with: :page_not_found
|
rescue_from Pundit::NilPolicyError, with: :page_not_found
|
||||||
rescue_from ActionController::RoutingError, with: :page_not_found
|
rescue_from ActionController::RoutingError, with: :page_not_found
|
||||||
|
@ -115,6 +116,16 @@ class ApplicationController < ActionController::Base
|
||||||
def after_sign_in_path_for(resource)
|
def after_sign_in_path_for(resource)
|
||||||
session[:locale] = nil
|
session[:locale] = nil
|
||||||
|
|
||||||
sites_path
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
# Guardar la ubicación para que devise redirija a donde íbamos, a
|
||||||
|
# menos que estemos recibiendo información o intentando ingresar.
|
||||||
|
def store_location!
|
||||||
|
return if request.xhr?
|
||||||
|
return unless request.request_method_symbol == :GET
|
||||||
|
return if devise_controller? && !is_a?(Devise::RegistrationsController) && params[:action] != 'edit'
|
||||||
|
|
||||||
|
session[:usuarie_return_to] = request.fullpath
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
106
app/javascript/controllers/dropdown_controller.js
Normal file
106
app/javascript/controllers/dropdown_controller.js
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
import { Controller } from "stimulus";
|
||||||
|
|
||||||
|
// https://getbootstrap.com/docs/4.6/components/dropdowns/#single-button
|
||||||
|
export default class extends Controller {
|
||||||
|
static targets = ["dropdown", "button", "item"];
|
||||||
|
|
||||||
|
// Al iniciar el controlador
|
||||||
|
connect() {
|
||||||
|
// Llevar la cuenta del item con foco
|
||||||
|
this.data.set("item", -1);
|
||||||
|
|
||||||
|
// Gestionar las teclas
|
||||||
|
this.keydownEvent = this.keydown.bind(this);
|
||||||
|
this.element.addEventListener("keydown", this.keydownEvent);
|
||||||
|
|
||||||
|
// Gestionar el foco
|
||||||
|
this.focusinEvent = this.focusin.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Al eliminar el controlador (al pasar a otra página)
|
||||||
|
disconnect() {
|
||||||
|
// Eliminar la gestión de teclas
|
||||||
|
this.element.removeEventListener("keydown", this.keydownEvent);
|
||||||
|
// Eliminar la gestión del foco
|
||||||
|
document.removeEventListener("focusin", this.focusinEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostrar u ocultar
|
||||||
|
toggle(event) {
|
||||||
|
(this.buttonTarget.ariaExpanded === "false") ? this.show() : this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostrar
|
||||||
|
show() {
|
||||||
|
this.buttonTarget.ariaExpanded = "true";
|
||||||
|
this.element.classList.add("show");
|
||||||
|
this.dropdownTarget.classList.add("show");
|
||||||
|
|
||||||
|
// Activar la gestión del foco
|
||||||
|
document.addEventListener("focusin", this.focusinEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ocultar
|
||||||
|
hide() {
|
||||||
|
this.buttonTarget.ariaExpanded = "false";
|
||||||
|
this.element.classList.remove("show");
|
||||||
|
this.dropdownTarget.classList.remove("show");
|
||||||
|
// Volver al inicio el foco de items
|
||||||
|
this.data.set("item", -1);
|
||||||
|
|
||||||
|
// Desactivar la gestión del foco
|
||||||
|
document.removeEventListener("focusin", this.focusinEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gestionar el foco
|
||||||
|
focusin(event) {
|
||||||
|
const item = this.itemTargets.find(x => x === event.target);
|
||||||
|
|
||||||
|
// Si el foco se coloca sobre elementos del controlador, no hacer
|
||||||
|
// nada
|
||||||
|
if (event.target === this.buttonTarget || item) {
|
||||||
|
// Si es un item, el comportamiento de las flechas verticales y el
|
||||||
|
// Tab tiene que ser igual
|
||||||
|
if (item) this.data.set("item", this.itemTargets.indexOf(item));
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// De lo contrario, ocultar
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gestionar las teclas
|
||||||
|
keydown(event) {
|
||||||
|
const initial = parseInt(this.data.get("item"));
|
||||||
|
let item = initial;
|
||||||
|
|
||||||
|
switch (event.keyCode) {
|
||||||
|
case 27:
|
||||||
|
// Esc cierra el menú y devuelve el foco
|
||||||
|
this.hide();
|
||||||
|
this.buttonTarget.focus();
|
||||||
|
break;
|
||||||
|
case 38:
|
||||||
|
// Moverse hacia arriba con tope en el primer item
|
||||||
|
if (item > -1) item--;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
// Moverse hacia abajo con tope en el último ítem, si el
|
||||||
|
// dropdown estaba cerrado, abrirlo.
|
||||||
|
if (item === -1) this.show();
|
||||||
|
if (item <= this.itemTargets.length) item++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si cambió la posición del ítem, darle foco y actualizar el
|
||||||
|
// contador.
|
||||||
|
if (initial !== item) {
|
||||||
|
this.itemTargets[item]?.focus();
|
||||||
|
|
||||||
|
this.data.set("item", item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -87,7 +87,7 @@ class DeployDistributedPress < Deploy
|
||||||
# @return [Array]
|
# @return [Array]
|
||||||
def gateway_urls
|
def gateway_urls
|
||||||
remote_info.dig(:distributed_press, :links)&.values&.map do |protocol|
|
remote_info.dig(:distributed_press, :links)&.values&.map do |protocol|
|
||||||
[ protocol[:link], protocol[:gateway] ]
|
[protocol[:link]]
|
||||||
end&.flatten&.compact&.select do |link|
|
end&.flatten&.compact&.select do |link|
|
||||||
link.include? '://'
|
link.include? '://'
|
||||||
end || []
|
end || []
|
||||||
|
|
|
@ -387,9 +387,11 @@ class Site < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def reload
|
def reload
|
||||||
super
|
super.tap do |s|
|
||||||
reload_jekyll!
|
reload_jekyll!
|
||||||
end
|
end
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
def configuration
|
def configuration
|
||||||
return @configuration if @configuration
|
return @configuration if @configuration
|
||||||
|
|
34
app/views/components/_dropdown.haml
Normal file
34
app/views/components/_dropdown.haml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
-#
|
||||||
|
@param :text [String] Contenido del botón
|
||||||
|
@param :button_classes [Array] Clases para el botón
|
||||||
|
@param :dropdown_classes [Array] Clases para el listado
|
||||||
|
@yield Un bloque que renderiza components/dropdown_item
|
||||||
|
- button_classes = local_assigns[:button_classes]&.join(' ')
|
||||||
|
- dropdown_classes = local_assigns[:dropdown_classes]&.join(' ')
|
||||||
|
|
||||||
|
.btn-group{
|
||||||
|
data: {
|
||||||
|
controller: 'dropdown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%button.btn.dropdown-toggle{
|
||||||
|
type: 'button',
|
||||||
|
class: button_classes,
|
||||||
|
data: {
|
||||||
|
toggle: 'true',
|
||||||
|
display: 'static',
|
||||||
|
action: 'dropdown#toggle',
|
||||||
|
target: 'dropdown.button'
|
||||||
|
},
|
||||||
|
aria: {
|
||||||
|
expanded: 'false'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
= text
|
||||||
|
.dropdown-menu{
|
||||||
|
class: dropdown_classes,
|
||||||
|
data: {
|
||||||
|
target: 'dropdown.dropdown'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
= yield
|
4
app/views/components/_dropdown_item.haml
Normal file
4
app/views/components/_dropdown_item.haml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
-#
|
||||||
|
@param :text [String] Contenido del link
|
||||||
|
@param :path [String] Link
|
||||||
|
= link_to text, path, class: 'dropdown-item', data: { target: 'dropdown.item' }
|
Loading…
Reference in a new issue