Skip to content

Commit

Permalink
Add circle posts history support (#18)
Browse files Browse the repository at this point in the history
* Wip: make web backend

* Wip: keep statuses if edit circle

* Wip: Add circle history page and record circle posts

* Add circle post to history in web ui when post

* Add test
  • Loading branch information
kmycode authored Sep 24, 2023
1 parent 0a42f4b commit df3b3f4
Show file tree
Hide file tree
Showing 19 changed files with 544 additions and 15 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
98 changes: 96 additions & 2 deletions app/javascript/mastodon/actions/circles.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import api from '../api';
import api, { getLinks } from '../api';

import { showAlertForError } from './alerts';
import { importFetchedAccounts } from './importer';
import { importFetchedAccounts, importFetchedStatuses } from './importer';

export const CIRCLE_FETCH_REQUEST = 'CIRCLE_FETCH_REQUEST';
export const CIRCLE_FETCH_SUCCESS = 'CIRCLE_FETCH_SUCCESS';
Expand Down Expand Up @@ -50,6 +50,14 @@ export const CIRCLE_ADDER_CIRCLES_FETCH_REQUEST = 'CIRCLE_ADDER_CIRCLES_FETCH_RE
export const CIRCLE_ADDER_CIRCLES_FETCH_SUCCESS = 'CIRCLE_ADDER_CIRCLES_FETCH_SUCCESS';
export const CIRCLE_ADDER_CIRCLES_FETCH_FAIL = 'CIRCLE_ADDER_CIRCLES_FETCH_FAIL';

export const CIRCLE_STATUSES_FETCH_REQUEST = 'CIRCLE_STATUSES_FETCH_REQUEST';
export const CIRCLE_STATUSES_FETCH_SUCCESS = 'CIRCLE_STATUSES_FETCH_SUCCESS';
export const CIRCLE_STATUSES_FETCH_FAIL = 'CIRCLE_STATUSES_FETCH_FAIL';

export const CIRCLE_STATUSES_EXPAND_REQUEST = 'CIRCLE_STATUSES_EXPAND_REQUEST';
export const CIRCLE_STATUSES_EXPAND_SUCCESS = 'CIRCLE_STATUSES_EXPAND_SUCCESS';
export const CIRCLE_STATUSES_EXPAND_FAIL = 'CIRCLE_STATUSES_EXPAND_FAIL';

export const fetchCircle = id => (dispatch, getState) => {
if (getState().getIn(['circles', id])) {
return;
Expand Down Expand Up @@ -370,3 +378,89 @@ export const removeFromCircleAdder = circleId => (dispatch, getState) => {
dispatch(removeFromCircle(circleId, getState().getIn(['circleAdder', 'accountId'])));
};

export function fetchCircleStatuses(circleId) {
return (dispatch, getState) => {
if (getState().getIn(['circles', circleId, 'statuses', 'isLoading'])) {
return;
}

dispatch(fetchCircleStatusesRequest(circleId));

api(getState).get(`/api/v1/circles/${circleId}/statuses`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(fetchCircleStatusesSuccess(circleId, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchCircleStatusesFail(circleId, error));
});
};
}

export function fetchCircleStatusesRequest(id) {
return {
type: CIRCLE_STATUSES_FETCH_REQUEST,
id,
};
}

export function fetchCircleStatusesSuccess(id, statuses, next) {
return {
type: CIRCLE_STATUSES_FETCH_SUCCESS,
id,
statuses,
next,
};
}

export function fetchCircleStatusesFail(id, error) {
return {
type: CIRCLE_STATUSES_FETCH_FAIL,
id,
error,
};
}

export function expandCircleStatuses(circleId) {
return (dispatch, getState) => {
const url = getState().getIn(['circles', circleId, 'statuses', 'next'], null);

if (url === null || getState().getIn(['circles', circleId, 'statuses', 'isLoading'])) {
return;
}

dispatch(expandCircleStatusesRequest(circleId));

api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(expandCircleStatusesSuccess(circleId, response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandCircleStatusesFail(circleId, error));
});
};
}

export function expandCircleStatusesRequest(id) {
return {
type: CIRCLE_STATUSES_EXPAND_REQUEST,
id,
};
}

export function expandCircleStatusesSuccess(id, statuses, next) {
return {
type: CIRCLE_STATUSES_EXPAND_SUCCESS,
id,
statuses,
next,
};
}

export function expandCircleStatusesFail(id, error) {
return {
type: CIRCLE_STATUSES_EXPAND_FAIL,
id,
error,
};
}

15 changes: 15 additions & 0 deletions app/javascript/mastodon/actions/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export const COMPOSE_DIRECT = 'COMPOSE_DIRECT';
export const COMPOSE_MENTION = 'COMPOSE_MENTION';
export const COMPOSE_RESET = 'COMPOSE_RESET';

export const COMPOSE_WITH_CIRCLE_SUCCESS = 'COMPOSE_WITH_CIRCLE_SUCCESS';

export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST';
export const COMPOSE_UPLOAD_SUCCESS = 'COMPOSE_UPLOAD_SUCCESS';
export const COMPOSE_UPLOAD_FAIL = 'COMPOSE_UPLOAD_FAIL';
Expand Down Expand Up @@ -174,6 +176,7 @@ export function submitCompose(routerHistory) {
const status = getState().getIn(['compose', 'text'], '');
const media = getState().getIn(['compose', 'media_attachments']);
const statusId = getState().getIn(['compose', 'id'], null);
const circleId = getState().getIn(['compose', 'circle_id'], null);

if ((!status || !status.length) && media.size === 0) {
return;
Expand Down Expand Up @@ -253,6 +256,10 @@ export function submitCompose(routerHistory) {
insertIfOnline(`account:${response.data.account.id}`);
}

if (statusId === null && circleId !== null && circleId !== 0) {
dispatch(submitComposeWithCircleSuccess({ ...response.data }, circleId));
}

dispatch(showAlert({
message: statusId === null ? messages.published : messages.saved,
action: messages.open,
Expand All @@ -278,6 +285,14 @@ export function submitComposeSuccess(status) {
};
}

export function submitComposeWithCircleSuccess(status, circleId) {
return {
type: COMPOSE_WITH_CIRCLE_SUCCESS,
status,
circleId,
}
}

export function submitComposeFail(error) {
return {
type: COMPOSE_SUBMIT_FAIL,
Expand Down
Loading

0 comments on commit df3b3f4

Please sign in to comment.