mirror of
https://github.com/Retrospring/retrospring.git
synced 2024-11-20 14:29:53 +01:00
Merge branch 'main' into feature/theme-stimulus
This commit is contained in:
commit
de3e04812d
19 changed files with 838 additions and 62 deletions
76
.github/workflows/lint.yml
vendored
Normal file
76
.github/workflows/lint.yml
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
rubocop:
|
||||
name: Rubocop
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
- name: Run rubocop
|
||||
uses: reviewdog/action-rubocop@v2
|
||||
with:
|
||||
rubocop_version: gemfile
|
||||
rubocop_extensions: rubocop-rails:gemfile
|
||||
reporter: github-pr-check
|
||||
|
||||
eslint:
|
||||
name: ESLint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- name: Set up Node 14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
cache: 'yarn'
|
||||
- name: Install node modules
|
||||
run: |
|
||||
npm i -g yarn
|
||||
yarn install --frozen-lockfile
|
||||
- uses: reviewdog/action-eslint@v1
|
||||
with:
|
||||
reporter: github-check
|
||||
eslint_flags: '--ext .ts app/javascript'
|
||||
|
||||
haml-lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
- uses: patch-technology/action-haml-lint@0.4
|
||||
with:
|
||||
reporter: github-check
|
||||
rubocop_version: gemfile
|
||||
|
||||
stylelint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- name: Set up Node 14
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
cache: 'yarn'
|
||||
- name: Install node modules
|
||||
run: |
|
||||
npm i -g yarn
|
||||
yarn install --frozen-lockfile
|
||||
- name: stylelint
|
||||
uses: pixeldesu/action-stylelint@5ec750b03a94da735352bdb02e9dfc3d5af33aba
|
||||
with:
|
||||
github_token: ${{ secrets.github_token }}
|
||||
reporter: github-pr-check
|
||||
stylelint_input: 'app/assets/stylesheets/**/*.scss'
|
22
.github/workflows/retrospring.yml
vendored
22
.github/workflows/retrospring.yml
vendored
|
@ -52,6 +52,7 @@ jobs:
|
|||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '14'
|
||||
cache: 'yarn'
|
||||
- name: Copy default configuration
|
||||
run: |
|
||||
cp config/database.yml.postgres config/database.yml
|
||||
|
@ -78,24 +79,3 @@ jobs:
|
|||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
file: ./coverage/coverage.xml
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3.3.0
|
||||
- name: Install dependencies
|
||||
run: sudo apt update && sudo apt-get install -y libpq-dev libxml2-dev libxslt1-dev libmagickwand-dev imagemagick libidn11-dev
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true
|
||||
- name: Run rubocop
|
||||
uses: reviewdog/action-rubocop@v2
|
||||
with:
|
||||
rubocop_version: gemfile
|
||||
rubocop_extensions: rubocop-rails:gemfile
|
||||
reporter: github-pr-check
|
||||
- run: yarn install
|
||||
- uses: reviewdog/action-eslint@v1
|
||||
with:
|
||||
reporter: github-check
|
||||
eslint_flags: '--ext .ts app/javascript'
|
||||
|
|
29
.stylelintrc.json
Normal file
29
.stylelintrc.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"extends": [
|
||||
"stylelint-config-standard-scss"
|
||||
],
|
||||
"plugins": [
|
||||
"stylelint-scss"
|
||||
],
|
||||
"rules": {
|
||||
"scss/at-import-partial-extension": null,
|
||||
"scss/at-rule-no-unknown": true,
|
||||
"at-rule-no-unknown": null,
|
||||
"color-hex-length": "long",
|
||||
"color-hex-case": "upper",
|
||||
"comment-whitespace-inside": null,
|
||||
"declaration-block-no-duplicate-properties": true,
|
||||
"function-name-case": null,
|
||||
"max-empty-lines": 2,
|
||||
"number-leading-zero": "always",
|
||||
"no-descending-specificity": null,
|
||||
"no-duplicate-at-import-rules": true,
|
||||
"rule-empty-line-before": ["always-multi-line", {"ignore": ["after-comment"]}],
|
||||
"shorthand-property-no-redundant-values": [true, {"severity": "warning"}],
|
||||
"selector-class-pattern": null,
|
||||
"selector-id-pattern": null,
|
||||
"selector-max-id": 1,
|
||||
"string-quotes": "double",
|
||||
"value-keyword-case": "lower"
|
||||
}
|
||||
}
|
|
@ -184,7 +184,7 @@ GEM
|
|||
nokogiri (>= 1.5.11, < 2.0.0)
|
||||
formatador (1.1.0)
|
||||
glob (0.3.1)
|
||||
globalid (1.0.0)
|
||||
globalid (1.0.1)
|
||||
activesupport (>= 5.0)
|
||||
haml (6.1.1)
|
||||
temple (>= 0.8.2)
|
||||
|
@ -323,7 +323,7 @@ GEM
|
|||
activesupport (>= 3.0.0)
|
||||
questiongenerator (1.0.0)
|
||||
racc (1.6.2)
|
||||
rack (2.2.5)
|
||||
rack (2.2.6.2)
|
||||
rack-protection (2.2.2)
|
||||
rack
|
||||
rack-test (2.0.2)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import start from 'retrospring/common';
|
||||
import initAnswerbox from 'retrospring/features/answerbox/index';
|
||||
import initCapabilities from 'retrospring/features/capabilities';
|
||||
import initInbox from 'retrospring/features/inbox/index';
|
||||
import initUser from 'retrospring/features/user';
|
||||
import initSettings from 'retrospring/features/settings/index';
|
||||
|
@ -14,7 +13,6 @@ import initWebpush from 'retrospring/features/webpush';
|
|||
import initWebpushSettingsButtons from 'retrospring/features/webpush/settingsButtons';
|
||||
|
||||
start();
|
||||
document.addEventListener('turbo:load', initCapabilities);
|
||||
document.addEventListener('DOMContentLoaded', initAnswerbox);
|
||||
document.addEventListener('DOMContentLoaded', initInbox);
|
||||
document.addEventListener('DOMContentLoaded', initUser);
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
connect(): void {
|
||||
const capabilities = [];
|
||||
|
||||
if ('share' in navigator) {
|
||||
capabilities.push('cap-web-share');
|
||||
}
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
capabilities.push('cap-service-worker');
|
||||
}
|
||||
|
||||
if ('Notification' in window) {
|
||||
capabilities.push('cap-notification');
|
||||
}
|
||||
|
||||
this.element.classList.add(...capabilities);
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
export default (): void => {
|
||||
if ('share' in navigator) {
|
||||
document.body.classList.add('cap-web-share');
|
||||
}
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
document.body.classList.add('cap-service-worker');
|
||||
}
|
||||
|
||||
if ('Notification' in window) {
|
||||
document.body.classList.add('cap-notification');
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import CharacterCountWarningController from "retrospring/controllers/character_c
|
|||
import FormatPopupController from "retrospring/controllers/format_popup_controller";
|
||||
import CollapseController from "retrospring/controllers/collapse_controller";
|
||||
import ThemeController from "retrospring/controllers/theme_controller";
|
||||
import CapabilitiesController from "retrospring/controllers/capabilities_controller";
|
||||
|
||||
/**
|
||||
* This module sets up Stimulus and our controllers
|
||||
|
@ -18,6 +19,7 @@ export default function (): void {
|
|||
window['Stimulus'] = Application.start();
|
||||
window['Stimulus'].register('announcement', AnnouncementController);
|
||||
window['Stimulus'].register('autofocus', AutofocusController);
|
||||
window['Stimulus'].register('capabilities', CapabilitiesController);
|
||||
window['Stimulus'].register('character-count', CharacterCountController);
|
||||
window['Stimulus'].register('character-count-warning', CharacterCountWarningController);
|
||||
window['Stimulus'].register('collapse', CollapseController);
|
||||
|
|
|
@ -53,7 +53,7 @@ class User < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
|||
foreign_key: "banned_by_id",
|
||||
dependent: :nullify
|
||||
|
||||
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
|
||||
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]+\z/
|
||||
WEBSITE_REGEX = /https?:\/\/([A-Za-z.-]+)\/?(?:.*)/i
|
||||
|
||||
before_validation do
|
||||
|
@ -61,7 +61,12 @@ class User < ApplicationRecord # rubocop:disable Metrics/ClassLength
|
|||
end
|
||||
|
||||
validates :email, fake_email: true, typoed_email: true
|
||||
validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }, screen_name: true
|
||||
validates :screen_name,
|
||||
presence: true,
|
||||
format: { with: SCREEN_NAME_REGEX, message: I18n.t("activerecord.validation.user.screen_name.format") },
|
||||
length: { minimum: 1, maximum: 16 },
|
||||
uniqueness: { case_sensitive: false },
|
||||
screen_name: true
|
||||
|
||||
mount_uploader :profile_picture, ProfilePictureUploader, mount_on: :profile_picture_file_name
|
||||
process_in_background :profile_picture
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
·
|
||||
%a{ href: question_path(a.question.user.screen_name, a.question.id) }
|
||||
= t(".answers", count: a.question.answer_count)
|
||||
.answerbox__question-body{ data: { controller: "collapse" } }
|
||||
.answerbox__question-body{ data: { controller: a.question.long? ? "collapse" : nil } }
|
||||
.answerbox__question-text{ class: a.question.long? && !display_all ? "collapsed" : "", data: { collapse_target: "content" } }
|
||||
= question_markdown a.question.content
|
||||
- if a.question.long? && !display_all
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- if @question.nil?
|
||||
= render "answerbox/header", a: a, display_all: display_all
|
||||
.card-body
|
||||
.answerbox__answer-body{ data: { controller: "collapse" } }
|
||||
.answerbox__answer-body{ data: { controller: a.long? ? "collapse" : nil } }
|
||||
.answerbox__answer-text{ class: a.long? && !display_all ? "collapsed" : "", data: { collapse_target: "content" } }
|
||||
= markdown a.content
|
||||
- if a.long? && !display_all
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
·
|
||||
%a{ href: question_path(i.question.user.screen_name, i.question.id) }
|
||||
= t(".answers", count: i.question.answer_count)
|
||||
.answerbox__question-body{ data: { controller: "collapse" } }
|
||||
.answerbox__question-body{ data: { controller: i.question.long? ? "collapse" : nil } }
|
||||
.answerbox__question-text{ class: i.question.long? ? "collapsed" : "", data: { collapse_target: "content" } }
|
||||
= question_markdown i.question.content
|
||||
- if i.question.long?
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
= csrf_meta_tags
|
||||
= yield(:og)
|
||||
= yield(:meta)
|
||||
%body{ class: user_signed_in? ? '' : 'not-logged-in' }
|
||||
%body{ class: user_signed_in? ? nil : 'not-logged-in', data: { controller: "capabilities" } }
|
||||
- if user_signed_in?
|
||||
= render 'navigation/main'
|
||||
- else
|
||||
|
|
|
@ -8,12 +8,8 @@
|
|||
icon: 'inbox', icon_only: true
|
||||
- if APP_CONFIG.dig(:features, :discover, :enabled) || current_user.mod?
|
||||
= nav_entry t("navigation.discover"), discover_path, icon: 'compass', icon_only: true
|
||||
%li.nav-item
|
||||
%a.nav-link{ href: '#', data: { bs_toggle: 'dropdown', bs_target: '#rs-mobile-nav-notifications' }, aria: { controls: 'rs-mobile-nav-notifications', expanded: 'false' } }
|
||||
%i.fa{ class: "fa-#{notifications_icon}" }
|
||||
%span.visually-hidden= t("navigation.notifications")
|
||||
%span.badge.badge-pill.badge-primary= notification_count
|
||||
= render 'navigation/dropdown/notifications', notifications: notifications, size: "mobile"
|
||||
= nav_entry t("navigation.notifications"), notifications_path("all"), icon: notifications_icon,
|
||||
badge: notification_count, badge_color: "primary", icon_only: true
|
||||
%li.nav-item.profile--image-dropdown
|
||||
%a.nav-link{ href: '#', data: { bs_toggle: 'dropdown', bs_target: '#rs-mobile-nav-profile' }, aria: { controls: 'rs-mobile-nav-profile', expanded: 'false' } }
|
||||
%img.avatar-md.d-inline{ src: current_user.profile_picture.url(:small) }
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
= user_screen_name question.user, author_identifier: identifier, url: false
|
||||
- else
|
||||
= t("answerbox.header.asked_html", user: user_screen_name(question.user, author_identifier: identifier), time: time_tooltip(question))
|
||||
.answerbox__question-body{ data: { controller: "collapse" } }
|
||||
.answerbox__question-body{ data: { controller: question.long? ? "collapse" : nil } }
|
||||
.answerbox__question-text{ class: question.long? ? "collapsed" : "", data: { collapse_target: "content" } }
|
||||
= question_markdown question.content
|
||||
- if question.long?
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
- type ||= nil
|
||||
.card.questionbox{ data: { id: q.id } }
|
||||
.card-body
|
||||
.card-body{ data: { controller: q.long? ? "collapse" : nil } }
|
||||
.d-flex
|
||||
- if type == 'discover'
|
||||
.flex-shrink-0
|
||||
|
@ -13,8 +13,10 @@
|
|||
·
|
||||
%a{ href: question_path(q.user.screen_name, q.id) }
|
||||
= pluralize(q.answer_count, t("voc.answer"))
|
||||
.answerbox__question-text
|
||||
.answerbox__question-text{ class: q.long? ? 'collapsed' : '', data: { collapse_target: "content" } }
|
||||
= question_markdown q.content
|
||||
- if q.long?
|
||||
= render "shared/collapse", type: "question"
|
||||
- if user_signed_in?
|
||||
.flex-shrink-0.ms-auto
|
||||
.btn-group
|
||||
|
|
|
@ -82,6 +82,7 @@ en:
|
|||
updated_at: "Account updated at"
|
||||
help:
|
||||
user:
|
||||
screen_name: "Alphanumerical and underscores allowed, max. 16 characters"
|
||||
email: "Don't forget to check your spam folder in case our email might have landed there!"
|
||||
current_password: "We need your current password to confirm your changes"
|
||||
profile:
|
||||
|
@ -95,6 +96,10 @@ en:
|
|||
primary_color: "The primary/brand colour of the site, used for navigation, links, etc."
|
||||
success_color: "Colour used for messages if something went through successfully."
|
||||
warning_color: "Colour used for warnings if something non-critical has happened."
|
||||
validation:
|
||||
user:
|
||||
screen_name:
|
||||
format: "contains invalid characters"
|
||||
helpers:
|
||||
submit:
|
||||
user:
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"scripts": {
|
||||
"lint": "yarn run eslint --ext .ts app/javascript",
|
||||
"lint:fix": "yarn run eslint --ext .ts app/javascript --fix",
|
||||
"lint:css": "yarn run stylelint \"app/assets/stylesheets/**/*.scss\"",
|
||||
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
|
||||
"build:css": "sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules"
|
||||
},
|
||||
|
@ -28,6 +29,9 @@
|
|||
"@typescript-eslint/parser": "^4.11.0",
|
||||
"esbuild": "^0.17.0",
|
||||
"eslint": "^7.16.0",
|
||||
"eslint-plugin-import": "^2.27.4"
|
||||
"eslint-plugin-import": "^2.27.4",
|
||||
"stylelint": "^14.16.1",
|
||||
"stylelint-config-standard-scss": "^6.1.0",
|
||||
"stylelint-scss": "^4.3.0"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue