diff --git a/app/assets/stylesheets/atoms/_a-dropdown.sass b/app/assets/stylesheets/atoms/_a-dropdown.sass new file mode 100644 index 00000000000..c38fbe94133 --- /dev/null +++ b/app/assets/stylesheets/atoms/_a-dropdown.sass @@ -0,0 +1,10 @@ +.a-dropdown + overflow: hidden + background-color: $base + border: solid 1px $border-shade + box-shadow: rgba(black, .2) 0 0 .375rem + border-radius: .25rem + +.a-dropdown__item + &:not(:last-child) + border-bottom: solid 1px $border diff --git a/app/assets/stylesheets/blocks/header/_.header-notification-icon.sass b/app/assets/stylesheets/blocks/header/_.header-notification-icon.sass new file mode 100644 index 00000000000..baec03ddd12 --- /dev/null +++ b/app/assets/stylesheets/blocks/header/_.header-notification-icon.sass @@ -0,0 +1,50 @@ +.header-notification-icon + +text-block(1.25rem 1, center) + +media-breakpoint-down(sm) + +text-block(1.125rem 1) + .has-count & + color: $default-text + +.header-notification-count + background-color: $badge-color + +text-block(.625rem 1, center $reversal-text flex) + align-items: center + justify-content: center + border-radius: 1rem + position: absolute + +media-breakpoint-up(md) + +size(1.25rem .875rem) + +position(right .25rem, top .25rem) + +media-breakpoint-down(sm) + +size(1.125rem .75rem) + +position(right .125rem, top .125rem) + +.header-notifications-item__body + width: 100% + +media-breakpoint-up(md) + color: $default-text + +media-breakpoint-down(sm) + color: $reversal-text + +.header-notifications-item__user-icon + float: left + +size(2rem) + margin-right: .5rem + margin-bottom: .25rem + +.header-notifications-item__message + p + line-height: 1.45 + margin-bottom: .375em + +media-breakpoint-up(md) + font-size: .8125rem + +media-breakpoint-down(sm) + font-size: .75rem + +.header-notifications-item__created-at + text-align: right + display: block + +media-breakpoint-up(md) + font-size: .75rem + +media-breakpoint-down(sm) + font-size: .625rem diff --git a/app/assets/stylesheets/blocks/header/_header-drop-down.sass b/app/assets/stylesheets/blocks/header/_header-drop-down.sass deleted file mode 100644 index 97c1d60b5d9..00000000000 --- a/app/assets/stylesheets/blocks/header/_header-drop-down.sass +++ /dev/null @@ -1,119 +0,0 @@ -.header-drop-down - +position(absolute, left 50%, top 3.5rem) - width: 16rem - margin-left: -7rem - display: none - +media-breakpoint-down(sm) - margin-left: -10rem - top: 2.5rem - .header-links__item.is-active &, - .header-show-mobile-nav.is-active & - display: block - -.header-drop-down__items - border: solid 1px #ccc - box-shadow: rgba(black, .1) 0 .0625rem .0625rem - background-color: $base - border-radius: .45rem - +position(relative, 2) - +media-breakpoint-down(sm) - width: 14rem - top: .5rem - &::before - content: "" - +size(0) - display: block - border-style: solid - border-width: 10px 10px - border-color: transparent - border-bottom-color: #ccc - +position(absolute, left 50%, top -20px) - margin-left: -10px - +media-breakpoint-down(sm) - left: 71% - &::after - content: "" - +size(0) - display: block - border-style: solid - border-width: 10px 10px - border-color: transparent - border-bottom-color: $base - +position(absolute, left 50%, top -18px) - margin-left: -10px - +media-breakpoint-down(sm) - left: 71% - -.header-drop-down__item - cursor: pointer - -.header-drop-down__item:not(:last-child) - border-bottom: solid 1px $background - -.header-drop-down__item-link - +text-block(.875rem 1.6, block $main) - padding: .5rem .75rem - transition: all .2s ease-in - .header-drop-down__item:first-child & - +border-radius(top, .25rem) - .header-drop-down__item:last-child & - +border-radius(bottom, .25rem) - &:hover - background-color: $background-more-tint - - - - -.header-notification-icon - +text-block(1.25rem 1, center) - +media-breakpoint-down(sm) - +text-block(1.125rem 1) - .has-count & - color: $default-text - -.header-notification-count - background-color: $badge-color - +text-block(.625rem 1, center $reversal-text flex) - align-items: center - justify-content: center - border-radius: 1rem - position: absolute - +media-breakpoint-up(md) - +size(1.25rem .875rem) - +position(right .25rem, top .25rem) - +media-breakpoint-down(sm) - +size(1.125rem .75rem) - +position(right .125rem, top .125rem) - -.header-notifications-item__body - width: 100% - +media-breakpoint-up(md) - color: $default-text - +media-breakpoint-down(sm) - color: $reversal-text - -.header-notifications-item__user-icon - float: left - +size(2rem) - margin-right: .5rem - margin-bottom: .25rem - -.header-notifications-item__message - p - line-height: 1.45 - margin-bottom: .375em - +media-breakpoint-up(md) - font-size: .8125rem - +media-breakpoint-down(sm) - font-size: .75rem - -.header-notifications-item_created-at - text-align: right - display: block - +media-breakpoint-up(md) - font-size: .75rem - +media-breakpoint-down(sm) - font-size: .625rem - -.header-drop-down__overlay - +position(fixed, left 0, top 0, right 0, bottom 0, 1) diff --git a/app/assets/stylesheets/blocks/header/_header-dropdown.sass b/app/assets/stylesheets/blocks/header/_header-dropdown.sass index 9fed3dc5956..3cef8269344 100644 --- a/app/assets/stylesheets/blocks/header/_header-dropdown.sass +++ b/app/assets/stylesheets/blocks/header/_header-dropdown.sass @@ -16,8 +16,8 @@ .header-dropdown__inner +media-breakpoint-up(md) - background-color: $base +position(absolute, right 0, top 100%, 2) + background-color: $base border: solid 1px $border-shade width: 14rem box-shadow: rgba(black, .2) 0 0 .375rem @@ -63,7 +63,7 @@ .header-dropdown__item:not(:last-child) & border-bottom: solid 1px $background &:hover - background-color: $background-more-tint + background-color: $hover-background +media-breakpoint-down(sm) color: $reversal-text border-bottom: solid 1px $side-border diff --git a/app/assets/stylesheets/blocks/page/_page-tabs.sass b/app/assets/stylesheets/blocks/page/_page-tabs.sass index 974811ea124..a73a9428abc 100644 --- a/app/assets/stylesheets/blocks/page/_page-tabs.sass +++ b/app/assets/stylesheets/blocks/page/_page-tabs.sass @@ -31,7 +31,7 @@ .page-tabs__item-link +flex-link - +text-block(.825rem 1, $default-text 600) + +text-block(.825rem 1, $semi-muted-text 600) align-items: center justify-content: center height: 2.75rem diff --git a/app/assets/stylesheets/blocks/shared/_tab-nav.sass b/app/assets/stylesheets/blocks/shared/_tab-nav.sass index 77ddfa29a86..0101424e07a 100644 --- a/app/assets/stylesheets/blocks/shared/_tab-nav.sass +++ b/app/assets/stylesheets/blocks/shared/_tab-nav.sass @@ -25,14 +25,14 @@ .tab-nav__item-link +block-link - +text-block(.75rem 2.3, $muted-text center nowrap) + +text-block(.75rem 2.3, $semi-muted-text center nowrap) background-color: $background-shade border-radius: 20rem width: 7rem transition: all.2s ease-out &:hover background-color: shade($background-shade, 10%) - color: $main-text + color: $default-text &.is-active background-color: $accent - color: $main-text + color: $default-text diff --git a/app/assets/stylesheets/blocks/user/_following.sass b/app/assets/stylesheets/blocks/user/_following.sass new file mode 100644 index 00000000000..23bed703446 --- /dev/null +++ b/app/assets/stylesheets/blocks/user/_following.sass @@ -0,0 +1,32 @@ +.following + position: relative + +.following__dropdown + +position(absolute, 2) + width: 18.75rem + +.following-option + cursor: pointer + width: 100% + padding: .75rem + display: block + text-align: left + transition: all .2s ease-out + &:hover + background-color: $hover-background + +.following-option__inner + position: relative + padding-left: 1.5rem + .following-option.is-active &::before + +fa(fas '\f00c') + +position(absolute, left 0, top 0) + +.following-option__label + +text-block(.875rem 1.4, 600 $semi-muted-text) + .following-option.is-active & + color: $default-text + +.following-option__desciption + +text-block(.75rem 1.5, $muted-text) + margin-top: .125rem diff --git a/app/assets/stylesheets/initializers/_reset.sass b/app/assets/stylesheets/initializers/_reset.sass index d474b5d355f..37e171d17a7 100644 --- a/app/assets/stylesheets/initializers/_reset.sass +++ b/app/assets/stylesheets/initializers/_reset.sass @@ -50,5 +50,6 @@ hr border: none details, -details * +details *, +summary box-sizing: border-box diff --git a/app/assets/stylesheets/mixins/_button.sass b/app/assets/stylesheets/mixins/_button.sass index e74570c05ae..ded79fb04c9 100644 --- a/app/assets/stylesheets/mixins/_button.sass +++ b/app/assets/stylesheets/mixins/_button.sass @@ -15,6 +15,7 @@ &.is-block display: flex width: 100% + max-width: 100% &.is-select +margin(horizontal, 0) &:focus @@ -30,7 +31,6 @@ margin-right: .35em margin-top: .02em font-size: 1.07em - font-weight: normal &.is-icon i +text-block(1.3em 1) diff --git a/app/assets/stylesheets/variables/_colors.sass b/app/assets/stylesheets/variables/_colors.sass index 263d2b38485..9e408ecdf60 100644 --- a/app/assets/stylesheets/variables/_colors.sass +++ b/app/assets/stylesheets/variables/_colors.sass @@ -5,6 +5,8 @@ $background: #ececec $background-shade: #d6d6d6 $background-tint: #eceeef $background-more-tint: #f7f7f9 +$hover-background: $background-more-tint + $default-text: #403f47 $reversal-text: white diff --git a/app/controllers/api/followings_controller.rb b/app/controllers/api/followings_controller.rb index c88af55e8ac..ffdd969255b 100644 --- a/app/controllers/api/followings_controller.rb +++ b/app/controllers/api/followings_controller.rb @@ -5,13 +5,24 @@ class API::FollowingsController < API::BaseController def create user = User.find(params[:id]) - if current_user.follow(user) + watch = params[:watch] == 'true' + if current_user.follow(user, watch: watch) render json: { id: user.id } else head :bad_request end end + def update + user = User.find(params[:id]) + watch = params[:watch] == 'true' + if current_user.change_watching(user, watch) + head :no_content + else + head :bad_request + end + end + def destroy user = User.find(params[:id]) if current_user.unfollow(user) diff --git a/app/controllers/api/users_controller.rb b/app/controllers/api/users_controller.rb index 7bbb461791e..813800fbb43 100644 --- a/app/controllers/api/users_controller.rb +++ b/app/controllers/api/users_controller.rb @@ -9,11 +9,11 @@ def index @tag = params[:tag] @target = params[:target] @target = 'student_and_trainee' unless target_allowlist.include?(@target) + @watch = params[:watch] target_users = if @target == 'followings' - followings = Following.where(follower_id: current_user.id).select('followed_id') - User.where(id: followings) + current_user.following_list(watch: @watch) elsif params[:tag] User.tagged_with(params[:tag]) else diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 42de99ff5a8..18175b4e3df 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -9,11 +9,11 @@ class UsersController < ApplicationController def index @target = params[:target] @target = 'student_and_trainee' unless target_allowlist.include?(@target) + @watch = params[:watch] target_users = if @target == 'followings' - followings = Following.where(follower_id: current_user.id).select('followed_id') - User.where(id: followings) + current_user.following_list(watch: @watch) elsif params[:tag] User.tagged_with(params[:tag]) else diff --git a/app/javascript/following.js b/app/javascript/following.js index 893f7113574..ef86f606acd 100644 --- a/app/javascript/following.js +++ b/app/javascript/following.js @@ -8,13 +8,15 @@ document.addEventListener('DOMContentLoaded', () => { const following = followings[i] const isFollowing = following.getAttribute('data-is-following') const userId = following.getAttribute('data-user-id') + const isWatching = following.getAttribute('data-is-watching') new Vue({ render: (h) => h(Following, { props: { isFollowing: isFollowing === 'true', - userId: Number(userId) + userId: Number(userId), + isWatching: isWatching === 'true' } }) }).$mount('.js-following') diff --git a/app/javascript/following.vue b/app/javascript/following.vue index 42cfd66bd0b..5a84aefd77f 100644 --- a/app/javascript/following.vue +++ b/app/javascript/following.vue @@ -1,9 +1,69 @@ - diff --git a/app/javascript/notifications_bell.vue b/app/javascript/notifications_bell.vue index 230fd55cc12..569ff812d23 100644 --- a/app/javascript/notifications_bell.vue +++ b/app/javascript/notifications_bell.vue @@ -29,7 +29,7 @@ li.header-links__item(v-bind:class='hasCountClass') ) .header-notifications-item__message p.test-notification-message {{ notification.message }} - time.header-notifications-item_created-at {{ createdAtFromNow(notification.created_at) }} + time.header-notifications-item__created-at {{ createdAtFromNow(notification.created_at) }} footer.header-dropdown__footer a.header-dropdown__footer-link(href='/notifications?status=unread') 全ての未読通知 a.header-dropdown__footer-link(href='/notifications') 全ての通知 diff --git a/app/javascript/user-secret-attributes.vue b/app/javascript/user-secret-attributes.vue index 3061323721f..a507b22032c 100644 --- a/app/javascript/user-secret-attributes.vue +++ b/app/javascript/user-secret-attributes.vue @@ -27,6 +27,11 @@ :class='{ "is-important": isInactive }' ) | {{ user.updated_at }} + .user-secret-attributes__action(v-if='currentUser.admin') + a.card-main-actions__action.a-button.is-sm.is-secondary.is-block( + :href='user.edit_admin_user_path' + ) + | 管理者として変更