Skip to content

Commit

Permalink
Wip: Add circle history page and record circle posts
Browse files Browse the repository at this point in the history
  • Loading branch information
kmycode committed Sep 23, 2023
1 parent 9212f82 commit c3d665f
Show file tree
Hide file tree
Showing 14 changed files with 155 additions and 10 deletions.
66 changes: 66 additions & 0 deletions app/controllers/api/v1/circles/statuses_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# frozen_string_literal: true

class Api::V1::Circles::StatusesController < Api::BaseController
before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:show]
before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:show]

before_action :require_user!
before_action :set_circle

after_action :insert_pagination_headers, only: :show

def show
@statuses = load_statuses
render json: @statuses, each_serializer: REST::StatusSerializer
end

private

def set_circle
@circle = current_account.circles.find(params[:circle_id])
end

def load_statuses
if unlimited?
@circle.statuses.includes(:status_stat).all
else
@circle.statuses.includes(:status_stat).paginate_by_max_id(limit_param(DEFAULT_STATUSES_LIMIT), params[:max_id], params[:since_id])
end
end

def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end

def next_path
return if unlimited?

api_v1_circle_statuses_url pagination_params(max_id: pagination_max_id) if records_continue?
end

def prev_path
return if unlimited?

api_v1_circle_statuses_url pagination_params(since_id: pagination_since_id) unless @statuses.empty?
end

def pagination_max_id
@statuses.last.id
end

def pagination_since_id
@statuses.first.id
end

def records_continue?
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end

def pagination_params(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end

def unlimited?
params[:limit] == '0'
end
end
7 changes: 5 additions & 2 deletions app/javascript/mastodon/features/circle_statuses/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { connect } from 'react-redux';

import { debounce } from 'lodash';

import { deleteCircle, expandCircleStatuses, fetchCircle, fetchCircleStatuses , setupCircleEditor } from 'mastodon/actions/circles';
import { deleteCircle, expandCircleStatuses, fetchCircle, fetchCircleStatuses } from 'mastodon/actions/circles';
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
import { openModal } from 'mastodon/actions/modal';
import ColumnHeader from 'mastodon/components/column_header';
Expand Down Expand Up @@ -80,7 +80,10 @@ class CircleStatuses extends ImmutablePureComponent {
};

handleEditClick = () => {
this.props.dispatch(setupCircleEditor(this.props.params.id));
this.props.dispatch(openModal({
modalType: 'CIRCLE_EDITOR',
modalProps: { circleId: this.props.params.id },
}));
};

handleDeleteClick = () => {
Expand Down
6 changes: 1 addition & 5 deletions app/javascript/mastodon/features/circles/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { fetchCircles, deleteCircle } from 'mastodon/actions/circles';
import { openModal } from 'mastodon/actions/modal';
import Column from 'mastodon/components/column';
import ColumnHeader from 'mastodon/components/column_header';
import { IconButton } from 'mastodon/components/icon_button';
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
import ScrollableList from 'mastodon/components/scrollable_list';
import ColumnLink from 'mastodon/features/ui/components/column_link';
Expand Down Expand Up @@ -106,10 +105,7 @@ class Circles extends ImmutablePureComponent {
bindToDocument={!multiColumn}
>
{circles.map(circle =>
(<div key={circle.get('id')} className='circle-item'>
<ColumnLink to={`#`} data-id={circle.get('id')} onClick={this.handleEditClick} icon='user-circle' text={circle.get('title')} />
<IconButton icon='trash' data_id={circle.get('id')} onClick={this.handleRemoveClick} />
</div>)
<ColumnLink key={circle.get('id')} to={`/circles/${circle.get('id')}`} icon='user-circle' text={circle.get('title')} />,
)}
</ScrollableList>

Expand Down
2 changes: 2 additions & 0 deletions app/javascript/mastodon/features/ui/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import {
Lists,
Antennas,
Circles,
CircleStatuses,
AntennaSetting,
Directory,
Explore,
Expand Down Expand Up @@ -259,6 +260,7 @@ class SwitchingColumnsArea extends PureComponent {
<WrappedRoute path='/mutes' component={Mutes} content={children} />
<WrappedRoute path='/lists' component={Lists} content={children} />
<WrappedRoute path='/antennasw' component={Antennas} content={children} />
<WrappedRoute path='/circles/:id' component={CircleStatuses} content={children} />
<WrappedRoute path='/circles' component={Circles} content={children} />

<Route component={BundleColumnError} />
Expand Down
4 changes: 4 additions & 0 deletions app/javascript/mastodon/features/ui/util/async-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ export function Circles () {
return import(/* webpackChunkName: "features/circles" */'../../circles');
}

export function CircleStatuses () {
return import(/* webpackChunkName: "features/circle_statuses" */'../../circle_statuses');
}

export function Status () {
return import(/* webpackChunkName: "features/status" */'../../status');
}
Expand Down
10 changes: 9 additions & 1 deletion app/javascript/mastodon/reducers/circles.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
import { List as ImmutableList, Map as ImmutableMap, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';

import {
CIRCLE_FETCH_SUCCESS,
Expand All @@ -17,6 +17,12 @@ import {

const initialState = ImmutableList();

const initialStatusesState = ImmutableMap({
items: ImmutableList(),
isLoading: false,
next: null,
});

const normalizeCircle = (state, circle) => {
const old = state.get(circle.id);
if (old === false) {
Expand All @@ -26,6 +32,8 @@ const normalizeCircle = (state, circle) => {
let s = state.set(circle.id, fromJS(circle));
if (old) {
s = s.setIn([circle.id, 'statuses'], old.get('statuses'));
} else {
s = s.setIn([circle.id, 'statuses'], initialStatusesState);
}
return s;
};
Expand Down
2 changes: 2 additions & 0 deletions app/models/circle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ class Circle < ApplicationRecord

has_many :circle_accounts, inverse_of: :circle, dependent: :destroy
has_many :accounts, through: :circle_accounts
has_many :circle_statuses, inverse_of: :circle, dependent: :destroy
has_many :statuses, through: :circle_statuses

validates :title, presence: true

Expand Down
26 changes: 26 additions & 0 deletions app/models/circle_status.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

# == Schema Information
#
# Table name: circle_statuses
#
# id :bigint(8) not null, primary key
# circle_id :bigint(8)
# status_id :bigint(8) not null
# created_at :datetime not null
# updated_at :datetime not null
#

class CircleStatus < ApplicationRecord
belongs_to :circle
belongs_to :status

validates :status, uniqueness: { scope: :circle }
validate :account_own_status

private

def account_own_status
errors.add(:status_id, :invalid) unless status.account_id == circle.account_id
end
end
1 change: 1 addition & 0 deletions app/models/status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class Status < ApplicationRecord
has_one :poll, inverse_of: :status, dependent: :destroy
has_one :trend, class_name: 'StatusTrend', inverse_of: :status
has_one :scheduled_expiration_status, inverse_of: :status, dependent: :destroy
has_one :circle_status, inverse_of: :status, dependent: :destroy

validates :uri, uniqueness: true, presence: true, unless: :local?
validates :text, presence: true, unless: -> { with_media? || reblog? }
Expand Down
2 changes: 2 additions & 0 deletions app/services/process_mentions_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,7 @@ def process_circle!
@circle.accounts.find_each do |target_account|
@current_mentions << @status.mentions.new(silent: true, account: target_account) unless mentioned_account_ids.include?(target_account.id)
end

@circle.statuses << @status
end
end
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
/lists/(*any)
/antennasw/(*any)
/antennast/(*any)
/circles
/circles/(*any)
/notifications
/favourites
/emoji_reactions
Expand Down
1 change: 1 addition & 0 deletions config/routes/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@

resources :circles, only: [:index, :create, :show, :update, :destroy] do
resource :accounts, only: [:show, :create, :destroy], controller: 'circles/accounts'
resource :statuses, only: [:show], controller: 'circles/statuses'
end

resources :bookmark_categories, only: [:index, :create, :show, :update, :destroy] do
Expand Down
22 changes: 22 additions & 0 deletions db/migrate/20230923103430_create_circle_statuses.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require Rails.root.join('lib', 'mastodon', 'migration_helpers')

class CreateCircleStatuses < ActiveRecord::Migration[7.0]
include Mastodon::MigrationHelpers

disable_ddl_transaction!

def change
safety_assured do
create_table :circle_statuses do |t|
t.belongs_to :circle, null: true, foreign_key: { on_delete: :cascade }
t.belongs_to :status, null: false, foreign_key: { on_delete: :cascade }
t.datetime :created_at, null: false
t.datetime :updated_at, null: false
end

add_index :circle_statuses, [:circle_id, :status_id], unique: true
end
end
end
14 changes: 13 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_09_19_232836) do
ActiveRecord::Schema[7.0].define(version: 2023_09_23_103430) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -447,6 +447,16 @@
t.index ["follow_id"], name: "index_circle_accounts_on_follow_id"
end

create_table "circle_statuses", force: :cascade do |t|
t.bigint "circle_id"
t.bigint "status_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["circle_id", "status_id"], name: "index_circle_statuses_on_circle_id_and_status_id", unique: true
t.index ["circle_id"], name: "index_circle_statuses_on_circle_id"
t.index ["status_id"], name: "index_circle_statuses_on_status_id"
end

create_table "circles", force: :cascade do |t|
t.bigint "account_id", null: false
t.string "title", default: "", null: false
Expand Down Expand Up @@ -1414,6 +1424,8 @@
add_foreign_key "circle_accounts", "accounts", on_delete: :cascade
add_foreign_key "circle_accounts", "circles", on_delete: :cascade
add_foreign_key "circle_accounts", "follows", on_delete: :cascade
add_foreign_key "circle_statuses", "circles", on_delete: :cascade
add_foreign_key "circle_statuses", "statuses", on_delete: :cascade
add_foreign_key "circles", "accounts", on_delete: :cascade
add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade
add_foreign_key "conversation_mutes", "conversations", on_delete: :cascade
Expand Down

0 comments on commit c3d665f

Please sign in to comment.