diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..44610e5 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..92b2793 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.direnv diff --git a/README.md b/README.md index 14d339b..815b72e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ # tachikoma -Patchset for Akkoma \ No newline at end of file +Patchset for Akkoma + +## patchlists + +### akkoma (backend) + +_none_ + +### akkoma-fe (frontend) + +- 0001-confirm-favorite: opens a "confirmation" modal on favorites, identical to reposts. (TODO: undo formatting changes) +- 0002-move-notifications: moves toast notifications to the bottom of the screen diff --git a/akkoma-fe/0001-confirm-favorite.patch b/akkoma-fe/0001-confirm-favorite.patch new file mode 100644 index 0000000..52de84d --- /dev/null +++ b/akkoma-fe/0001-confirm-favorite.patch @@ -0,0 +1,144 @@ +diff --git a/src/components/favorite_button/favorite_button.js b/src/components/favorite_button/favorite_button.js +index d15699f7..e5f1a3c5 100644 +--- a/src/components/favorite_button/favorite_button.js ++++ b/src/components/favorite_button/favorite_button.js +@@ -1,41 +1,60 @@ +-import { mapGetters } from 'vuex' +-import { library } from '@fortawesome/fontawesome-svg-core' +-import { faStar } from '@fortawesome/free-solid-svg-icons' +-import { +- faStar as faStarRegular +-} from '@fortawesome/free-regular-svg-icons' ++import ConfirmModal from "../confirm_modal/confirm_modal.vue"; ++import { mapGetters } from "vuex"; ++import { library } from "@fortawesome/fontawesome-svg-core"; ++import { faStar } from "@fortawesome/free-solid-svg-icons"; ++import { faStar as faStarRegular } from "@fortawesome/free-regular-svg-icons"; + +-library.add( +- faStar, +- faStarRegular +-) ++library.add(faStar, faStarRegular); + + const FavoriteButton = { +- props: ['status', 'loggedIn'], +- data () { ++ props: ["status", "loggedIn"], ++ components: { ++ ConfirmModal, ++ }, ++ data() { + return { +- animated: false +- } ++ animated: false, ++ showingConfirmDialog: false, ++ }; + }, + methods: { +- favorite () { ++ favorite() { ++ if (!this.status.favorited && this.shouldConfirmFavorite) { ++ this.showConfirmDialog(); ++ } else { ++ this.doFavorite(); ++ } ++ }, ++ doFavorite() { + if (!this.status.favorited) { +- this.$store.dispatch('favorite', { id: this.status.id }) ++ this.$store.dispatch("favorite", { id: this.status.id }); + } else { +- this.$store.dispatch('unfavorite', { id: this.status.id }) ++ this.$store.dispatch("unfavorite", { id: this.status.id }); + } +- this.animated = true ++ this.animated = true; + setTimeout(() => { +- this.animated = false +- }, 500) +- } ++ this.animated = false; ++ }, 500); ++ this.hideConfirmDialog(); ++ }, ++ showConfirmDialog() { ++ this.showingConfirmDialog = true; ++ }, ++ hideConfirmDialog() { ++ this.showingConfirmDialog = false; ++ }, + }, + computed: { +- ...mapGetters(['mergedConfig']), +- remoteInteractionLink () { +- return this.$store.getters.remoteInteractionLink({ statusId: this.status.id }) +- } +- } +-} ++ ...mapGetters(["mergedConfig"]), ++ shouldConfirmFavorite() { ++ return this.mergedConfig.modalOnFavorite; ++ }, ++ remoteInteractionLink() { ++ return this.$store.getters.remoteInteractionLink({ ++ statusId: this.status.id, ++ }); ++ }, ++ }, ++}; + +-export default FavoriteButton ++export default FavoriteButton; +diff --git a/src/components/favorite_button/favorite_button.vue b/src/components/favorite_button/favorite_button.vue +index 16bf441e..06ed7d59 100644 +--- a/src/components/favorite_button/favorite_button.vue ++++ b/src/components/favorite_button/favorite_button.vue +@@ -32,6 +32,18 @@ + > + {{ status.fave_num }} + ++ ++ ++ {{ $t('status.favorite_confirm') }} ++ ++ + + + +diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue +index 64950f8a..b09c6d9f 100644 +--- a/src/components/settings_modal/tabs/general_tab.vue ++++ b/src/components/settings_modal/tabs/general_tab.vue +@@ -282,6 +282,11 @@ + {{ $t('settings.confirm_dialogs_repeat') }} + + ++
  • ++ ++ {{ $t('settings.confirm_dialogs_favorite') }} ++ ++
  • +
  • + + {{ $t('settings.confirm_dialogs_unfollow') }} +diff --git a/src/modules/config.js b/src/modules/config.js +index 551b5bb6..0e78c749 100644 +--- a/src/modules/config.js ++++ b/src/modules/config.js +@@ -83,6 +83,7 @@ export const defaultState = { + // This hides statuses filtered via a word filter + hideFilteredStatuses: undefined, // instance default + modalOnRepeat: undefined, // instance default ++ modalOnFavorite: undefined, // instance default + modalOnUnfollow: undefined, // instance default + modalOnBlock: undefined, // instance default + modalOnMute: undefined, // instance default diff --git a/akkoma-fe/0002-move-notifications.patch b/akkoma-fe/0002-move-notifications.patch new file mode 100644 index 0000000..48cc26d --- /dev/null +++ b/akkoma-fe/0002-move-notifications.patch @@ -0,0 +1,13 @@ +diff --git a/src/components/global_notice_list/global_notice_list.vue b/src/components/global_notice_list/global_notice_list.vue +index ddc45b81..492fc4b6 100644 +--- a/src/components/global_notice_list/global_notice_list.vue ++++ b/src/components/global_notice_list/global_notice_list.vue +@@ -29,7 +29,7 @@ + + .global-notice-list { + position: fixed; +- top: 50px; ++ bottom: 5px; + width: 100%; + pointer-events: none; + z-index: 1001; diff --git a/akkoma-fe/upstream.txt b/akkoma-fe/upstream.txt new file mode 100644 index 0000000..30eb958 --- /dev/null +++ b/akkoma-fe/upstream.txt @@ -0,0 +1 @@ +7cc6c3565466b330043e0a811a6e1e2db487ec8d \ No newline at end of file diff --git a/akkoma/upstream.txt b/akkoma/upstream.txt new file mode 100644 index 0000000..141dcc0 --- /dev/null +++ b/akkoma/upstream.txt @@ -0,0 +1 @@ +26a91d5c9eef1b2c75d3e0e7cc792d62e953cb30 \ No newline at end of file diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..8a5f168 --- /dev/null +++ b/flake.nix @@ -0,0 +1,76 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + }; + + outputs = { self, nixpkgs, ...} @ inputs: let + systems = [ + "aarch64-linux" + "x86_64-linux" + ]; + forAllSystems = nixpkgs.lib.genAttrs systems; + in rec { + devShells = forAllSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}; + in pkgs.mkShell { + buildInputs = with pkgs; [ + just + ]; + } + ); + + nixosModules = rec { + default = enableTachikoma; + enableTachikoma = { pkgs, ...}: { + services.akkoma.package = packages.${pkgs.system}.akkoma.tachikoma; + services.akkoma.frontends.primary = { + name = "tachikoma-fe"; + ref = "stable"; + package = packages.${pkgs.system}.akkoma-frontends.tachikoma-fe; + }; + }; + }; + + packages = forAllSystems (system: let + pkgs = nixpkgs.legacyPackages.${system}; + lib = pkgs.lib; + patchSet = dirPath: builtins.filterList (file: lib.strings.hasSuffix ".patch" file) (builtins.attrNames (builtins.readDir dirPath)); + in rec { + default = akkoma.tachikoma; + + akkoma.tachikoma = let + rev = builtins.readFile ./akkoma/upstream.txt; + in pkgs.akkoma.overrideAttrs (final: prev: { + version = "${rev}-tachikoma"; + + src = fetchFromGitea { + inherit rev; + domain = "akkoma.dev"; + owner = "AkkomaGang"; + repo = "akkoma"; + hash = "sha256-MPUZFcIxZ21fe3edwi+/Kt8qpwNBCh40wheC3QMqw2M="; + }; + + patches = prev.patches ++ patchSet ./akkoma; + patchFlags = "-p1 -F5"; + }); + + akkoma-frontends.tachikoma-fe = let + rev = builtins.readFile ./akkoma-fe/upstream.txt; + in pkgs.akkoma-frontends.tachikoma-fe.overrideAttrs (final: prev: { + version = "${rev}-tachikoma"; + + src = fetchFromGitea { + inherit rev; + domain = "akkoma.dev"; + owner = "AkkomaGang"; + repo = "akkoma-fe"; + hash = "sha256-MPUZFcIxZ21fe3edwi+/Kt8qpwNBCh40wheC3QMqw2M="; + }; + + patches = prev.patches ++ patchSet ./akkoma-fe; + patchFlags = "-p1 -F5"; + }); + }); + }; +}