Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6215e4c
WIP: new logo, new layout (both authenticated and guest), feed, whole…
mdshack Jul 27, 2024
07e88f7
feat: reusable shot feed + serve /feed route
mdshack Jul 27, 2024
0e0a5ad
feat: collection carousels
mdshack Jul 27, 2024
eafba7b
feat: commenting on shots
mdshack Jul 28, 2024
f2e32ce
feat: more info tab for shot.show, consolidate dupe logic in upload c…
mdshack Jul 28, 2024
5a62c1d
feat: condensed comment view for feeds
mdshack Jul 28, 2024
52d3d9a
feat: reaction progress, reusable cursor paginated resource (+ commen…
mdshack Jul 28, 2024
7219274
feat: reactions + better factories
mdshack Jul 28, 2024
9eb1309
feat: explore
mdshack Jul 28, 2024
8161d35
feat: unauthaticated dialog hooks, login button
mdshack Jul 28, 2024
8867007
fix: various unauthenticated bugs, readd 'og' meta properties
mdshack Jul 28, 2024
2c73339
feat: delete shot
mdshack Jul 28, 2024
696c13e
feat: dialog update shots + move create dialog to component
mdshack Jul 28, 2024
49eb181
chore: tweaks to v2 readme
mdshack Aug 3, 2024
65e6197
chore: prerelease
mdshack Aug 3, 2024
3e37c3f
fix: prerelease
mdshack Aug 3, 2024
16a4d18
fix: dont publish latest tag
mdshack Aug 3, 2024
299e0dd
fix: move to new action + drop manifest content
mdshack Aug 3, 2024
81a9b9b
fix: target branch v2
mdshack Aug 3, 2024
5aab2a5
fix: always bump prerelease
mdshack Aug 3, 2024
5c39ba6
fix: prerelease version
mdshack Aug 4, 2024
2208441
fix: drop release manifest
mdshack Aug 4, 2024
4b88445
fix: empty json
mdshack Aug 4, 2024
162f886
chore: drop release changes
mdshack Aug 4, 2024
de45019
feat: share videos
mdshack Aug 4, 2024
d891291
feat: strip exif + docs update + include runtime deps in dockerfile
mdshack Aug 4, 2024
b4bf69e
feat: update handle + ui consistency
mdshack Aug 4, 2024
5cfd254
fix: null safety on card shot, bug with file input, uploading state f…
mdshack Aug 4, 2024
da69fc0
chore (docs): new banner
mdshack Aug 4, 2024
41014b2
chore (docs): new banner
mdshack Aug 4, 2024
1f5a059
chore (docs): new banner
mdshack Aug 4, 2024
f2d34d2
feat: new runtime image + autorelease on push to main under 'v2.0.0-b…
mdshack Aug 4, 2024
5e005e7
chore: release on push to v2
mdshack Aug 4, 2024
33f095b
chore: access
mdshack Aug 4, 2024
240d6e9
chore: lower to php82
mdshack Aug 4, 2024
aa7dcdd
feat: autoplay video in view
mdshack Aug 4, 2024
b550eea
chore: bump back to 83
mdshack Aug 4, 2024
4670447
fix: imagick@master
mdshack Aug 4, 2024
98d94a0
chore: add flags capability
mdshack Aug 4, 2024
c8b81c1
chore: copy .
mdshack Aug 4, 2024
44cd3d4
fix: migration failure if info isnt set
mdshack Aug 21, 2024
38d57ad
fix: check mime exists too
mdshack Aug 21, 2024
8efc837
fix: only show registration if available
mdshack Aug 21, 2024
28a5518
fix: handle uneven video height/widths (these currently fail when exp…
mdshack Aug 23, 2024
bfdda82
chore: bump ffmpeg preset speed from medium to veryfast
mdshack Aug 23, 2024
d34bde1
chore: only export to mid bitrate
mdshack Aug 30, 2024
4ce8434
chore: highbitrate + ultrafast
mdshack Aug 30, 2024
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
Binary file modified .assets/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 0 additions & 14 deletions .docker/Caddyfile

This file was deleted.

80 changes: 51 additions & 29 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,52 @@
FROM mdshack/php:8.3-fpm-alpine-caddy

ARG CI=false

ENV XDG_CONFIG_HOME /config
ENV XDG_DATA_HOME /data

EXPOSE 80
EXPOSE 443
#################
# Backend Setup #
#################
FROM composer:2.2 as phpsetup

WORKDIR /app

COPY . /app/

# Install backend dependencies
RUN if [[ $CI != *"true"* ]]; \
then composer install --ignore-platform-reqs --optimize-autoloader --no-interaction; \
else composer install --ignore-platform-reqs --optimize-autoloader --no-interaction --no-dev; \
fi

RUN composer dump-autoload

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer

# Install Node/NPM
RUN apk add --update --no-cache nodejs npm
##################
# Frontend Setup #
##################
FROM node:lts-alpine3.18 as nodesetup

WORKDIR /app

# Install frontend dependencies
COPY package*.json /app
RUN npm install --omit optional

COPY . /app/
COPY --from=phpsetup /app/vendor /app/vendor

# Build Frontend
RUN npm run build


###########
# Runtime #
###########
FROM dunglas/frankenphp:php8.3-alpine

WORKDIR /app

# Runtime requirements
RUN apk add --update --no-cache ffmpeg
# fix: imagick/imagick@master - https://github.com/Imagick/imagick/issues/643#issuecomment-2086949716
RUN install-php-extensions \
dom \
fileinfo \
Expand All @@ -26,29 +57,20 @@ RUN install-php-extensions \
xmlwriter \
pcntl \
pdo_mysql \
pdo_pgsql


# Install frontend dependencies
COPY package*.json /app
RUN npm install --omit optional
pdo_pgsql \
imagick/imagick@master

# Copy Application
COPY --chown=www-data . /app
COPY . /app

RUN if [[ $CI != *"true"* ]]; \
then composer install --no-interaction --optimize-autoloader; \
else composer install --no-interaction --optimize-autoloader --no-dev; \
fi
RUN touch /app/.env

# Build Frontend
RUN npm run build
RUN mkdir /docker-init
COPY ./.docker/init/* /docker-init/

# Cleanup
RUN if [[ $CI != *"true"* ]] ; then rm -rf /app/node_modules /usr/local/bin/composer /usr/local/bin/npm /usr/local/bin/node /usr/local/lib/node_modules ; fi
COPY ./.docker/entrypoint /usr/local/bin

COPY --chown=www-data ./.docker/Caddyfile /etc/caddy/Caddyfile
COPY --chown=www-data ./.docker/init/* /docker-init/
COPY --from=nodesetup /app/public/build /app/public/build
COPY --from=phpsetup /app/vendor /app/vendor

RUN touch /app/.env
RUN chown www-data:www-data /app/.env
ENTRYPOINT [ "entrypoint" ]
14 changes: 14 additions & 0 deletions .docker/entrypoint
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

HOST="${HOST:-0.0.0.0}"
ADMIN_PORT="${ADMIN_PORT:-2019}"
PORT="${PORT:-80}"
FLAGS="${FLAGS}"

for file in "/docker-init"/*; do
if [ -f "$file" ]; then
/bin/sh $file
fi
done

php artisan octane:frankenphp --host=$HOST --admin-port=$ADMIN_PORT --port=$PORT $FLAGS
6 changes: 6 additions & 0 deletions .docker/init/03_config_cache
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ DEVELOP="${DEVELOP:-false}"
if [[ $DEVELOP != *"true"* ]];then
echo "Caching application configuration"
php artisan config:cache

echo "Caching routes"
php artisan route:cache

echo "Caching views"
php artisan view:cache
fi
50 changes: 16 additions & 34 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,45 +1,27 @@
on:
push:
branches:
- main
- v2

name: release-please
name: release

jobs:
release-please:
runs-on: ubuntu-latest
steps:
- uses: google-github-actions/release-please-action@v4
id: release
with:
token: ${{ secrets.RELEASE_PLEASE_PAT }}
release-type: php
- uses: actions/checkout@v4

- uses: actions/checkout@v4
if: ${{ steps.release.outputs.release_created }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Get Docker image tag
id: get-tag
run: |
version=$(echo "${{ steps.release.outputs.tag_name }}" | sed -e "s/^v//")
echo "tag=$version" >> "$GITHUB_OUTPUT"
- name: Set up Docker Buildx
if: ${{ steps.release.outputs.release_created }}
uses: docker/setup-buildx-action@v3

- name: Login to Docker Hub
if: ${{ steps.release.outputs.release_created }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
if: ${{ steps.release.outputs.release_created }}
uses: docker/build-push-action@v5
with:
push: true
tags: mdshack/shotshare:latest,mdshack/shotshare:${{ steps.get-tag.outputs.tag }}
cache-from: type=registry,ref=mdshack/shotshare:latest
cache-to: type=inline
file: ./.docker/Dockerfile
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: mdshack/shotshare:v2.0.0-beta
cache-from: type=registry,ref=mdshack/shotshare:latest
cache-to: type=inline
file: ./.docker/Dockerfile
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ yarn-error.log
/.fleet
/.idea
/.vscode
frankenphp
frankenphp-worker.php
1 change: 1 addition & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
147 changes: 24 additions & 123 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,136 +16,37 @@

---

> [!WARNING]
> This branch is still in beta, please check the [main branch](https://github.com/mdshack/shotshare) for the latest stable releases.

## About

ShotShare is an open source, self hosted, bare bones image posting/sharing platform, it was built to allow friends to upload screenshots and send links to their friends without the constant barrage of ads/extraneous features.
ShotShare is an open source, self hosted, configurable media sharing platform, it was built to allow easy sharing of media between friends and communities.

### Features

> [!NOTE]
> Check indicates this feature is implemented, unchecked indicates it is a targeted feature

- [X] **Authentication** - Users may sign up and login to the platform.
- [X] **Image Sharing** - Share images with ease, upload a new shot from any page in the application.
- [X] **Video Sharing** - Share videos with your friends.
- [ ] **Administration** - Ability to administrate shots and users in your installation.
- [ ] **Invitations** - Invite users to the platform with a one-click sign up link.
- [ ] **S3 Support** - Support cloud-based storage with an S3 storage backend.

#### Optional

- [X] **Privacy Features** - Restrict sign ups, disallow non-users from seeing shots, and more.
- [X] **Social Functionality** - Follow your friends, react to their posts, add comments, and more!
- [X] **Feeds** - See what those you follow are posting in your Feed. See what others you aren't following are posting in the "Explore" feed.
- [X] **Screenshotting Clients** - Integrates with multiple major screenshot clients, such as: [ShareX](#) and [Shutter](#).
- [X] **EXIF Stripping** - Remove sensitive details from your uploaded images, such as location embeddings.

## Demo

A demo may be found [here](https://demo.shotshare.dev/). This environment is _strictly_ for trialing the application; images added here are automatically cleaned up after a few minutes.

## Installation, Configuration, & Local Development

ShotShare is meant to be extremely easy to self host. Below is a sample deployment using Docker.

### Example Deployment with Docker

1. Create a directory for ShotShare: `sudo mkdir /shotshare`
2. Create persistent files: `sudo touch /shotshare/.env /shotshare/database.sqlite`
3. Ensure the user/group 82 (`www-data` user in docker container) own the `.env` file: `sudo chown 82:82 /shotshare/.env /shotshare/database.sqlite`
4. Start the ShotShare container

_You may wish to customize environment variables (such as the `HOST`) before running this command, see below for a list of environment variables._

_If you used ShotShare before 1.5.1, the "database" mount has changed to a file bind, you will need to manually migrate your `database.sqlite` file to use these new commands._

#### Run in HTTPS mode

This will use Caddy's [Automatic HTTPs](https://caddyserver.com/docs/automatic-https) setup generate SSL certificates, handle renewals, and automagically redirect your visitors to HTTPS. For most scenarios, this is the "preferred" installation method.

```sh
docker run \
-p 80:80 \
-p 443:443 \
-e HOST=localhost \
-e FEATURE_UUID_ROUTES=true \
-v shotshare_caddy_data:/data/caddy \
-v shotshare_caddy_config:/config/caddy \
-v shotshare_data:/app/storage/app/uploads" \
--mount type=bind,source=/shotshare/database.sqlite,target=/app/database/database.sqlite \
--mount type=bind,source=/shotshare/.env,target=/app/.env \
-d \
--restart unless-stopped \
--name shotshare \
mdshack/shotshare:latest
```

#### Run in HTTP mode

This will _not_ issue any SSL and will just serve over HTTP. This may be useful if you plan to front ShotShare with your own reverse proxy.

If you plan to force HTTPS before it gets to ShotShare, you will also need to force ShotShare to utilize HTTPS links, you may do so by adding `-e FORCE_HTTPS=true`.

```sh
docker run \
-p 80:80 \
-e HOST=":80" \
-e FEATURE_UUID_ROUTES=true \
-v shotshare_data:/app/storage/app/uploads" \
--mount type=bind,source=/shotshare/database.sqlite,target=/app/database/database.sqlite \
--mount type=bind,source=/shotshare/.env,target=/app/.env \
-d \
--restart unless-stopped \
--name shotshare \
mdshack/shotshare:latest
```

### Configuration Options

_Note: These are not all of the configuration options, only the most used ones, feel free to open a PR if you see any missing. For a more in-depth look at all the available options check out [here](/config)._

| Environment Variable | Default | Options | Description |
| ------------- | ------------- | ------------- | ------------- |
| `ALLOW_REGISTRATION` | `true` | `true`, `false` | Allows new users to register |
| `DB_CONNECTION` | `sqlite` | `sqlite`,`mysql`,`pgsql`,`sqlsrv` | Indicates what database connection will be used |
| `DB_HOST` | `127.0.0.1` | _N/A_ | Not required if using `sqlite`, indicates the database host |
| `DB_PORT` | `3306` | _N/A_ | Not required if using `sqlite`, indicates the database port |
| `DB_DATABASE` | `shotshare` | _N/A_ | Not required if using `sqlite`, indicates the database database |
| `DB_USERNAME` | `shotshare` | _N/A_ | Not required if using `sqlite`, indicates the database username |
| `DB_PASSWORD` | _none_ | _N/A_ | Not required if using `sqlite`, indicates the database password |
| `FEATURE_REACTIONS` | `true` | `true`, `false` | Adds shot reactions (ability to upvote/downvote shots) |
| `FEATURE_UUID_ROUTES` | `false` | `true`, `false` | Utilizes UUIDs instead of IDs, will be the default in 2.0.0 |
| `FEATURE_FOOTER` | `true` | `true`, `false` | Adds credits footer ("Made with love" + "Check out source code"), leaving these should help generate additional traffic to this project, keeping it alive |
| `HOST` | localhost | _N/A_ | Public host used by Caddy, thanks to caddy, this host will automatically be issued a SSL certificate |
| `PHP_MEMORY_LIMIT` | `128M` | _N/A_ | Memory limit for PHP FPM |
| `PHP_UPLOAD_MAX_FILESIZE` | `2M` | _N/A_ | Max allowed upload size (Must include file size unit) |
| `PHP_MAX_UPLOADS` | `20` | _N/A_ | Max number of file uploads in a single request |
| `PHP_POST_MAX_SIZE` | `8M` | _N/A_ | Max size of a POST request |
| `SHOTS_LINKS_SHARE_LINK` | `true` | `true`, `false` | Indicates if the "Share Link" will be displayed on the shot screen |
| `SHOTS_LINKS_DIRECT_LINK` | `true` | `true`, `false` | Indicates if the "Direct Link" will be displayed on the shot screen |
| `SHOTS_LINKS_MARKDOWN_REDDIT` | `true` | `true`, `false` | Indicates if the "Markdown (Reddit)" link will be displayed on the shot screen |
| `SHOTS_LINKS_MARKDOWN_OTHER` | `true` | `true`, `false` | Indicates if the "Markdown (GitHub & StackOverflow)" link will be displayed on the shot screen |
| `SHOTS_LINKS_BBCODE` | `true` | `true`, `false` | Indicates if the "BBCode" link will be displayed on the shot screen |
| `SHOTS_LINKS_HTML` | `true` | `true`, `false` | Indicates if the "HTML" link will be displayed on the shot screen |

### Commands

_Note: these are all "artisan" commands, and thus must be prefixed with `php artisan` (ex. `php artisan shotshare:clean-images`). These also must be executed inside of your docker container, an easy way to do that is using `docker exec -it shotshare php artisan [command you wish to issue]`._

| Environment Variable | Description |
| ------------- | ------------- |
| `shotshare:clean-images` | Clears out all images (from storage and application) |
| `shotshare:create-user` | Creates a new user (useful for `ALLOW_REGISTRATION=false`) |

### Local Development

Local development is done using `docker compose`

1. Pull the repo: `git clone git@github.com:mdshack/shotshare.git`
2. Change to the ShotShare directory: `cd shotshare`
3. Install dependencies: `composer install; npm install`
4. Build frontend: `npm run build`
5. Start docker compose: `docker compose up`

### ShareX Setup

ShotShare is configured to work with [ShareX](https://getsharex.com/) a popular screenshot tool. Included in this repo is an [example configuration](/shotshare.sxcu) (`/shotshare.sxcu`). Below are a few instructions on how to get this running on your local install.

1. On your ShotShare profile page (when logged in it will be at `{your installation}/profile`), create a new API key
2. Copy the contents of `/shotshare.sxcu` into a notepad
3. Replace `{Your ShotShare URL}` with your ShotShare installation URL, for example `https://demo.shotshare.dev`
4. Replace `{Your API Key}` with the API key you created in step #1
5. Copy the contents of your modified `shotshare.sxcu`
6. In ShareX, click `Destinations -> Custom Uploader Settings -> Import -> From Clipboard`
7. On the main screen of ShareX, click `Destinations -> Image Uploader -> Custom Image Uploader`
8. Take a test snapshot (`ctrl` + `print screen`), ensure you get a link to ShotShare in your clipboard

### Shutter Setup

[Shutter](https://shutter-project.org) is an advanced screenshot tool for Linux, with support for custom upload plugins.

A plugin [has been created](https://github.com/bentasker/shutter-shotshare) to allow Shutter to upload screenshots and return the resulting ShotShare url.

## Contributing

There is currently no established pattern for contributing, if you see something missing or feel like something could be better feel free to pop open an issue and/or PR.
Expand Down
18 changes: 18 additions & 0 deletions app/Data/CommentData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App\Data;

use Carbon\Carbon;
use Spatie\LaravelData\Data;

class CommentData extends Data
{
public function __construct(
public int $id,
public string $contents,
public Carbon $created_at,
public Carbon $updated_at,

public ?UserData $user,
) {}
}
Loading