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

Update with stable changes #3

Closed
wants to merge 69 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
4198a7d
Revert "prototype: decreased rounding"
codingneko Oct 2, 2023
b755868
Revert "fix: css rounding"
codingneko Oct 2, 2023
e7619ac
Revert "fix: Admin menu css"
codingneko Oct 2, 2023
a846b4e
Revert "fix: css rounding in nav"
codingneko Oct 2, 2023
9b14170
Revert "test: change buttons and avatar"
codingneko Oct 2, 2023
9d8c3c2
No square avatars by default >:(
codingneko Oct 2, 2023
509929e
Remove reaction background and border
codingneko Oct 2, 2023
6b8a1da
Merge branch 'transfem-org:develop' into develop
codingneko Oct 3, 2023
4bb77ed
Merge branch 'transfem-org:develop' into develop
codingneko Oct 4, 2023
914d590
Merge branch 'transfem-org:develop' into develop
codingneko Oct 6, 2023
999cce4
Merge branch 'transfem-org:develop' into develop
codingneko Oct 9, 2023
5140e2c
Merge branch 'transfem-org:develop' into develop
codingneko Oct 12, 2023
2802e81
Revert "prototype: decreased rounding"
codingneko Oct 2, 2023
1173e5f
Revert "fix: css rounding"
codingneko Oct 2, 2023
71effaf
Revert "fix: Admin menu css"
codingneko Oct 2, 2023
012edfa
Revert "fix: css rounding in nav"
codingneko Oct 2, 2023
2c83a64
Revert "test: change buttons and avatar"
codingneko Oct 2, 2023
553ed4f
No square avatars by default >:(
codingneko Oct 2, 2023
61942f1
Remove reaction background and border
codingneko Oct 2, 2023
13ac94f
Merge branch 'develop' of https://github.com/codingneko/Sharkey into …
codingneko Oct 16, 2023
90319ae
Merge branch 'transfem-org:develop' into develop
codingneko Oct 18, 2023
6c982ea
merge: bring stable and develop on same commit history
Oct 19, 2023
ce7e23c
chore: update dev version
Oct 19, 2023
7739278
upd: don't show approved badge on remote users
Oct 19, 2023
059401a
fix: system users not being set to approved on creation
Oct 19, 2023
c3f7681
fix: invite code not being marked as used
Oct 19, 2023
c055578
chore: update readme
Insert5StarName Oct 19, 2023
e1e02a6
fix: being able to set birthday into the future
Oct 19, 2023
363092d
Merge branch 'develop' of https://github.com/transfem-org/Sharkey int…
Oct 19, 2023
d6ebbf5
fix: performance issues & respect blur option
Oct 19, 2023
4569520
fix: headers of containers
Oct 19, 2023
86f4191
revert: blur in container
Oct 19, 2023
fc5d75f
fix: no translations on sub notes
Oct 19, 2023
142f500
add: approval section in control panel
Oct 19, 2023
fd8fa9b
upd: remove approvals from admin-users
Oct 19, 2023
537af45
chore: lint on SkApprovalUser
Oct 19, 2023
659574e
upd: hide files in post form by default
Oct 19, 2023
4dda43d
upd: wrap username in header
Oct 19, 2023
71b7c31
upd: refetch user keys on signature failure
Oct 20, 2023
c76f0f1
fix: set boolean to true if uri doesn't match activity actor
Oct 20, 2023
33eab0d
upd: change handling of renewkeyFailed
Oct 20, 2023
8f7903c
upd: use favicon.png instead of favicon.ico as default image on Visit…
Oct 20, 2023
69ebee7
fix: change favicon to apple-touch-icon
Oct 20, 2023
01a142f
fix: increment and decrement of note count
Oct 21, 2023
1608e32
Merge branch 'develop' of https://github.com/transfem-org/Sharkey int…
Oct 21, 2023
9eb094a
fix: decrement happening on normal renotes
Oct 21, 2023
bd63970
chore: update compose example to use keydb and fix network related issue
Oct 21, 2023
b930b89
upd: send email on new pending approval
Oct 21, 2023
4a90464
fix: tabs not working on profile overview for notes
Oct 21, 2023
d392edb
test: more search options
Oct 21, 2023
a74c7f6
upd: search filters
Oct 21, 2023
ce83c48
add: view previous versions of notes
Oct 22, 2023
6b3b805
chore: remove debug from versions menu
Oct 22, 2023
d50e81e
upd: improve note edit table & improve previous version view
Oct 22, 2023
2706b6b
fix: date formatting in previous note view
Oct 22, 2023
83be996
upd: store old date and use it in previous versions
Oct 22, 2023
aaf55cf
revert: atempt pull to reload
Insert5StarName Oct 22, 2023
b74fd71
nicer file type search
dakkar Oct 22, 2023
7c922dc
fix: wakelock error causing site to not load
Oct 22, 2023
1dc5623
use block comment
dakkar Oct 22, 2023
16f671c
Merge branch 'develop' of https://github.com/transfem-org/Sharkey int…
Oct 22, 2023
b434025
merge: nicer file type search (#107)
Oct 22, 2023
d49099b
upd: add additional checks
Oct 22, 2023
6d29022
fix: not checking for renotes during packing of note
Oct 22, 2023
4a4fd70
upd: partially un-hash CSS class names
wont-work Oct 17, 2023
38412ee
merge: partially un-hash CSS class names (#109)
Oct 22, 2023
13c5da6
fix: MFM overflowing out of note
Oct 22, 2023
b0a7fd6
Merge branch 'develop' of https://github.com/transfem-org/Sharkey int…
Oct 22, 2023
4e07839
Merge branch 'transfem-org:develop' into develop
codingneko Oct 23, 2023
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
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@
## ✨ Features
- **ActivityPub support**\
Not on Sharkey? No problem! Not only can Sharkey instances talk to each other, but you can make friends with people on other networks like Mastodon and Pixelfed!
- **Reactions**\
You can add emoji reactions to any post! No longer are you bound by a like button, show everyone exactly how you feel with the tap of a button.
- **Post Editing**\
In Sharkey you can edit your post, this is not possible in normal Misskey
- **Federated Backgrounds and Music status**\
You can add a background to your profile as well as a music status via ListenBrainz, show everyone what music you are currently listening too
- **Mastodon API**\
Sharkey implements the Mastodon API unlike normal Misskey
- **UI/UX Improvements**\
Sharkey makes some UI/UX improvements to make it easier to navigate
- **Drive**\
With Sharkey's built in drive, you get cloud storage right in your social media, where you can upload any files, make folders, and find media from posts you've made!
- **Sign-Up Approval**\
With Sharkey, you can enable sign-ups, subject to manual moderator approval and mandatory user-provided reasons for joining.
- **Rich Web UI**\
Sharkey has a rich and easy to use Web UI!
It is highly customizable, from changing the layout and adding widgets to making custom themes.
Expand Down
8 changes: 3 additions & 5 deletions docker-compose.yml.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ version: "3"

services:
web:
# image: ghcr.io/transfem-org/sharkey:stable
build: .
restart: always
links:
Expand All @@ -17,20 +18,19 @@ services:
- "3000:3000"
networks:
- shonk
- web
volumes:
- ./files:/sharkey/files
- ./.config:/sharkey/.config:ro

redis:
restart: always
image: redis:7-alpine
image: eqalpha/keydb:latest
networks:
- shonk
volumes:
- ./redis:/data
healthcheck:
test: "redis-cli ping"
test: "keydb-cli ping"
interval: 5s
retries: 20

Expand Down Expand Up @@ -64,5 +64,3 @@ services:

networks:
shonk:
web:
external: true
1 change: 1 addition & 0 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ signup: "Sign Up"
uploading: "Uploading..."
save: "Save"
users: "Users"
approvals: "Approvals"
addUser: "Add a user"
favorite: "Add to favorites"
favorites: "Favorites"
Expand Down
1 change: 1 addition & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface Locale {
"uploading": string;
"save": string;
"users": string;
"approvals": string;
"addUser": string;
"favorite": string;
"favorites": string;
Expand Down
1 change: 1 addition & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ signup: "新規登録"
uploading: "アップロード中"
save: "保存"
users: "ユーザー"
approvals: "承認"
addUser: "ユーザーを追加"
favorite: "お気に入り"
favorites: "お気に入り"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sharkey",
"version": "2023.10.2",
"version": "2023.10.3.beta1",
"codename": "shonk",
"repository": {
"type": "git",
Expand Down
13 changes: 13 additions & 0 deletions packages/backend/migration/1697970083000-alterNoteEdit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export class AlterNoteEdit1697970083000 {
name = "AlterNoteEdit1697970083000";

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note_edit" RENAME COLUMN "text" TO "newText"`);
await queryRunner.query(`ALTER TABLE "note_edit" ADD COLUMN "oldText" text`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note_edit" RENAME COLUMN "newText" TO "text"`);
await queryRunner.query(`ALTER TABLE "note_edit" DROP COLUMN "oldText"`);
}
}
11 changes: 11 additions & 0 deletions packages/backend/migration/1697970083001-oldDateNoteEdit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class OldDateNoteEdit1697970083001 {
name = "OldDateNoteEdit1697970083001";

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "note_edit" ADD COLUMN "oldDate" TIMESTAMP WITH TIME ZONE`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "note_edit" DROP COLUMN "oldDate"`);
}
}
1 change: 1 addition & 0 deletions packages/backend/src/core/CreateSystemUserService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export class CreateSystemUserService {
isRoot: false,
isLocked: true,
isExplorable: false,
approved: true,
isBot: true,
}).then(x => transactionalEntityManager.findOneByOrFail(MiUser, x.identifiers[0]));

Expand Down
15 changes: 12 additions & 3 deletions packages/backend/src/core/NoteCreateService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,11 @@ export class NoteCreateService implements OnApplicationShutdown {
// Register host
if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.fetch(user.host).then(async i => {
this.instancesRepository.increment({ id: i.id }, 'notesCount', 1);
if (note.renote && note.text) {
this.instancesRepository.increment({ id: i.id }, 'notesCount', 1);
} else if (!note.renote) {
this.instancesRepository.increment({ id: i.id }, 'notesCount', 1);
}
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateNote(i.host, note, true);
}
Expand All @@ -520,8 +524,13 @@ export class NoteCreateService implements OnApplicationShutdown {
}
}

// Increment notes count (user)
this.incNotesCountOfUser(user);
if (data.renote && data.text) {
// Increment notes count (user)
this.incNotesCountOfUser(user);
} else if (!data.renote) {
// Increment notes count (user)
this.incNotesCountOfUser(user);
}

this.pushToTl(note, user);

Expand Down
25 changes: 24 additions & 1 deletion packages/backend/src/core/NoteDeleteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,21 @@ export class NoteDeleteService {
this.perUserNotesChart.update(user, note, false);
}

if (note.renoteId && note.text) {
// Decrement notes count (user)
this.decNotesCountOfUser(user);
} else if (!note.renoteId) {
// Decrement notes count (user)
this.decNotesCountOfUser(user);
}

if (this.userEntityService.isRemoteUser(user)) {
this.federatedInstanceService.fetch(user.host).then(async i => {
this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1);
if (note.renoteId && note.text) {
this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1);
} else if (!note.renoteId) {
this.instancesRepository.decrement({ id: i.id }, 'notesCount', 1);
}
if ((await this.metaService.fetch()).enableChartsForFederatedInstances) {
this.instanceChart.updateNote(i.host, note, false);
}
Expand Down Expand Up @@ -147,6 +159,17 @@ export class NoteDeleteService {
}
}

@bindThis
private decNotesCountOfUser(user: { id: MiUser['id']; }) {
this.usersRepository.createQueryBuilder().update()
.set({
updatedAt: new Date(),
notesCount: () => '"notesCount" - 1',
})
.where('id = :id', { id: user.id })
.execute();
}

@bindThis
private async findCascadingNotes(note: MiNote): Promise<MiNote[]> {
const recursive = async (noteId: string): Promise<MiNote[]> => {
Expand Down
188 changes: 98 additions & 90 deletions packages/backend/src/core/NoteEditService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,104 +387,112 @@ export class NoteEditService implements OnApplicationShutdown {
update.hasPoll = !!data.poll;
}

await this.noteEditRepository.insert({
id: this.idService.gen(),
noteId: oldnote.id,
text: data.text || undefined,
cw: data.cw,
fileIds: undefined,
updatedAt: new Date(),
});
if (Object.keys(update).length > 0) {
const exists = await this.noteEditRepository.findOneBy({ noteId: oldnote.id });

await this.noteEditRepository.insert({
id: this.idService.gen(),
noteId: oldnote.id,
oldText: update.text ? oldnote.text : undefined,
newText: update.text || undefined,
cw: update.cw || undefined,
fileIds: undefined,
oldDate: exists ? oldnote.updatedAt as Date : this.idService.parse(oldnote.id).date,
updatedAt: new Date(),
});

const note = new MiNote({
id: oldnote.id,
updatedAt: data.updatedAt ? data.updatedAt : new Date(),
fileIds: data.files ? data.files.map(file => file.id) : [],
replyId: data.reply ? data.reply.id : null,
renoteId: data.renote ? data.renote.id : null,
channelId: data.channel ? data.channel.id : null,
threadId: data.reply
? data.reply.threadId
const note = new MiNote({
id: oldnote.id,
updatedAt: data.updatedAt ? data.updatedAt : new Date(),
fileIds: data.files ? data.files.map(file => file.id) : [],
replyId: data.reply ? data.reply.id : null,
renoteId: data.renote ? data.renote.id : null,
channelId: data.channel ? data.channel.id : null,
threadId: data.reply
? data.reply.threadId
: data.reply.id
: null,
name: data.name,
text: data.text,
hasPoll: data.poll != null,
cw: data.cw ?? null,
tags: tags.map(tag => normalizeForSearch(tag)),
emojis,
reactions: oldnote.reactions,
userId: user.id,
localOnly: data.localOnly!,
reactionAcceptance: data.reactionAcceptance,
visibility: data.visibility as any,
visibleUserIds: data.visibility === 'specified'
? data.visibleUsers
? data.visibleUsers.map(u => u.id)
: []
: [],

attachedFileTypes: data.files ? data.files.map(file => file.type) : [],

// 以下非正規化データ
replyUserId: data.reply ? data.reply.userId : null,
replyUserHost: data.reply ? data.reply.userHost : null,
renoteUserId: data.renote ? data.renote.userId : null,
renoteUserHost: data.renote ? data.renote.userHost : null,
userHost: user.host,
});
? data.reply.threadId
: data.reply.id
: null,
name: data.name,
text: data.text,
hasPoll: data.poll != null,
cw: data.cw ?? null,
tags: tags.map(tag => normalizeForSearch(tag)),
emojis,
reactions: oldnote.reactions,
userId: user.id,
localOnly: data.localOnly!,
reactionAcceptance: data.reactionAcceptance,
visibility: data.visibility as any,
visibleUserIds: data.visibility === 'specified'
? data.visibleUsers
? data.visibleUsers.map(u => u.id)
: []
: [],

attachedFileTypes: data.files ? data.files.map(file => file.type) : [],

// 以下非正規化データ
replyUserId: data.reply ? data.reply.userId : null,
replyUserHost: data.reply ? data.reply.userHost : null,
renoteUserId: data.renote ? data.renote.userId : null,
renoteUserHost: data.renote ? data.renote.userHost : null,
userHost: user.host,
});

if (data.uri != null) note.uri = data.uri;
if (data.url != null) note.url = data.url;

if (mentionedUsers.length > 0) {
note.mentions = mentionedUsers.map(u => u.id);
const profiles = await this.userProfilesRepository.findBy({ userId: In(note.mentions) });
note.mentionedRemoteUsers = JSON.stringify(mentionedUsers.filter(u => this.userEntityService.isRemoteUser(u)).map(u => {
const profile = profiles.find(p => p.userId === u.id);
const url = profile != null ? profile.url : null;
return {
uri: u.uri,
url: url ?? undefined,
username: u.username,
host: u.host,
} as IMentionedRemoteUsers[0];
}));
}
if (data.uri != null) note.uri = data.uri;
if (data.url != null) note.url = data.url;

if (mentionedUsers.length > 0) {
note.mentions = mentionedUsers.map(u => u.id);
const profiles = await this.userProfilesRepository.findBy({ userId: In(note.mentions) });
note.mentionedRemoteUsers = JSON.stringify(mentionedUsers.filter(u => this.userEntityService.isRemoteUser(u)).map(u => {
const profile = profiles.find(p => p.userId === u.id);
const url = profile != null ? profile.url : null;
return {
uri: u.uri,
url: url ?? undefined,
username: u.username,
host: u.host,
} as IMentionedRemoteUsers[0];
}));
}

if (data.poll != null) {
// Start transaction
await this.db.transaction(async transactionalEntityManager => {
await transactionalEntityManager.update(MiNote, oldnote.id, note);

const poll = new MiPoll({
noteId: note.id,
choices: data.poll!.choices,
expiresAt: data.poll!.expiresAt,
multiple: data.poll!.multiple,
votes: new Array(data.poll!.choices.length).fill(0),
noteVisibility: note.visibility,
userId: user.id,
userHost: user.host,
});

if (data.poll != null) {
// Start transaction
await this.db.transaction(async transactionalEntityManager => {
await transactionalEntityManager.update(MiNote, oldnote.id, note);

const poll = new MiPoll({
noteId: note.id,
choices: data.poll!.choices,
expiresAt: data.poll!.expiresAt,
multiple: data.poll!.multiple,
votes: new Array(data.poll!.choices.length).fill(0),
noteVisibility: note.visibility,
userId: user.id,
userHost: user.host,
if (!oldnote.hasPoll) {
await transactionalEntityManager.insert(MiPoll, poll);
} else {
await transactionalEntityManager.update(MiPoll, oldnote.id, poll);
}
});
} else {
await this.notesRepository.update(oldnote.id, note);
}

if (!oldnote.hasPoll) {
await transactionalEntityManager.insert(MiPoll, poll);
} else {
await transactionalEntityManager.update(MiPoll, oldnote.id, poll);
}
});
setImmediate('post edited', { signal: this.#shutdownController.signal }).then(
() => this.postNoteEdited(note, user, data, silent, tags!, mentionedUsers!),
() => { /* aborted, ignore this */ },
);

return note;
} else {
await this.notesRepository.update(oldnote.id, note);
return oldnote;
}

setImmediate('post edited', { signal: this.#shutdownController.signal }).then(
() => this.postNoteEdited(note, user, data, silent, tags!, mentionedUsers!),
() => { /* aborted, ignore this */ },
);

return note;
}

@bindThis
Expand Down
Loading
Loading