Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add circle posts history support #18

Merged
merged 5 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading