-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from hyphacoop/initial
Initial Implementation
- Loading branch information
Showing
47 changed files
with
5,489 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# This is a basic workflow to help you get started with Actions | ||
|
||
name: CI | ||
|
||
# Controls when the action will run. | ||
on: | ||
# Triggers the workflow on push or pull request events but only for the main branch | ||
push: | ||
# TODO: Uncomment once released | ||
# branches: [ main ] | ||
|
||
# Allows you to run this workflow manually from the Actions tab | ||
workflow_dispatch: | ||
|
||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel | ||
jobs: | ||
# This workflow contains a single job called "build" | ||
build: | ||
# The type of runner that the job will run on | ||
runs-on: ubuntu-latest | ||
|
||
# Steps represent a sequence of tasks that will be executed as part of the job | ||
steps: | ||
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it | ||
- uses: actions/checkout@v2 | ||
- name: Publish to Distributed Press | ||
uses: hyphacoop/[email protected] | ||
with: | ||
publish_dir: ./ | ||
dp_url: https://api.distributed.press | ||
refresh_token: ${{ secrets.DISTRIBUTED_PRESS_TOKEN }} | ||
site_url: reader.distributed.press |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
# reader.distributed.press | ||
Read and follow federated microblogs. | ||
# Social Reader | ||
A P2P and offline-first ActivityPub client for reading and following microblogs on the Fediverse, avoiding dependency on always-online HTTP servers, allowing access to content anytime, anywhere. | ||
|
||
For more information, please visit [docs.distributed.press](https://docs.distributed.press/social-reader). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
.about-container { | ||
flex: 1; | ||
max-width: 600px; | ||
width: 100%; | ||
margin: 0 20px; | ||
margin-top: 10px; | ||
} | ||
|
||
/* Apply general styles to all section elements within about-container */ | ||
.about-container > section { | ||
text-align: left; | ||
color: var(--rdp-text-color); | ||
width: 100%; | ||
margin-bottom: 2rem; | ||
} | ||
|
||
.about-info a, | ||
.faq-section a { | ||
color: var(--rdp-link-color); | ||
text-decoration: underline; | ||
} | ||
|
||
.about-info a:hover, | ||
.faq-section a:hover { | ||
text-decoration: none; | ||
} | ||
|
||
.faq-section details { | ||
margin-bottom: 1rem; | ||
border-bottom: 1px solid var(--rdp-border-color); | ||
padding-bottom: 1rem; | ||
} | ||
|
||
.faq-section summary { | ||
font-weight: bold; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
<!DOCTYPE html> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||
<title>About Reader</title> | ||
<style> | ||
@import url("./about.css"); | ||
@import url("./common.css"); | ||
@import url("./theme.css"); | ||
@import url("./index.css"); | ||
@import url("./timeline.css"); | ||
@import url("./post.css"); | ||
</style> | ||
<div class="container"> | ||
<sidebar-nav></sidebar-nav> | ||
<section class="about-container main-content"> | ||
<section class="about-info"> | ||
<p> | ||
Social Reader is a P2P and offline ActivityPub client for reading and | ||
following microblogs on the | ||
<a href="https://en.wikipedia.org/wiki/Fediverse">Fediverse</a>. | ||
</p> | ||
<p> | ||
Unlike traditional platforms, Social Reader does not index data on a | ||
server. It empowers you to load public ActivityPub data directly, | ||
turning your device into a personal indexer. This means | ||
<b>your content, your control</b>. | ||
</p> | ||
<p> | ||
Social Reader natively supports content loading over P2P protocols such | ||
as | ||
<code><a href="https://ipfs.tech/">ipfs://</a></code> and | ||
<code><a href="https://holepunch.to/">hyper://</a></code | ||
>. This innovation bypasses the need for always-online HTTP servers, | ||
allowing you to access content anytime, anywhere—even offline. | ||
</p> | ||
<p> | ||
Social Reader is built on principles of low-tech; minimal dependencies, | ||
vanilla JavaScript, unminified scripts, and IndexedDB for local data | ||
storage. View and contribute to our open-source code on | ||
<a href="https://github.com/hyphacoop/reader.distributed.press" | ||
>GitHub</a | ||
>. | ||
</p> | ||
</section> | ||
<!-- FAQ Section --> | ||
<section class="faq-section"> | ||
<h2>FAQs</h2> | ||
<details open> | ||
<summary>How do I create an account on Social Reader?</summary> | ||
<p> | ||
Social Reader is designed as a reading and following client, which | ||
means you cannot create an account directly within the app. To | ||
actively write and contribute to the Fediverse, you would need to | ||
interact with the | ||
<a href="https://hypha.coop/dripline/announcing-dp-social-inbox/" | ||
>Social Inbox</a | ||
> | ||
API. This can be done through platforms like | ||
<a href="https://sutty.nl/">Sutty CMS</a> or by forking and hosting | ||
your own instance of | ||
<a href="https://github.com/RangerMauve/staticpub.mauve.moe" | ||
>Staticpub</a | ||
> | ||
repository. | ||
</p> | ||
</details> | ||
<details> | ||
<summary> | ||
Why is Social Reader different from mainstream social platforms? | ||
</summary> | ||
<p> | ||
Social Reader eliminates the middleman, ensuring direct communication | ||
with your audience without the interference of third-party algorithms. | ||
This ad-free experience prioritizes user autonomy and engagement, | ||
making it ideal for community leaders and organizations seeking | ||
genuine reach and engagement. Unlike traditional social networks where | ||
follower engagement often requires payment, Social Reader and the | ||
broader Fediverse allow for genuine reach and engagement. | ||
</p> | ||
</details> | ||
<details> | ||
<summary>I found a bug. Where do I report it?</summary> | ||
<p> | ||
If you encounter any issues or have feedback, please file a report on | ||
our | ||
<a | ||
href="https://github.com/hyphacoop/reader.distributed.press/issues/new" | ||
>GitHub issues</a | ||
> | ||
page. We appreciate your input as it helps us improve Social Reader | ||
for everyone. | ||
</p> | ||
</details> | ||
</section> | ||
</section> | ||
<div class="right-column"> | ||
<!-- This is an empty column to balance the layout --> | ||
</div> | ||
</div> | ||
<script type="module" src="./sidebar.js"></script> | ||
<script type="module" src="followed-accounts.js"></script> | ||
<script type="module" src="./theme-selector.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
.mini-profile { | ||
display: flex; | ||
align-items: center; | ||
text-align: left; | ||
cursor: pointer; | ||
background: none; | ||
border: none; | ||
padding: 0; | ||
margin-bottom: 4px; | ||
color: inherit; | ||
font: inherit; | ||
} | ||
|
||
.profile-mini-icon { | ||
width: 28px; | ||
height: 28px; | ||
border-radius: 50%; | ||
background-color: #000000; | ||
margin-right: 6px; | ||
} | ||
|
||
.profile-mini-name { | ||
color: var(--rdp-text-color); | ||
} | ||
|
||
.profile-followed-date { | ||
text-align: center; | ||
font-size: 0.875rem; | ||
color: var(--rdp-details-color); | ||
margin-left: 34px; | ||
margin-bottom: 6px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { db } from './dbInstance.js' | ||
|
||
class ActorMiniProfile extends HTMLElement { | ||
static get observedAttributes () { | ||
return ['url'] | ||
} | ||
|
||
constructor () { | ||
super() | ||
this.url = '' | ||
} | ||
|
||
connectedCallback () { | ||
this.url = this.getAttribute('url') | ||
this.fetchAndRenderActorInfo(this.url) | ||
} | ||
|
||
attributeChangedCallback (name, oldValue, newValue) { | ||
if (name === 'url' && newValue !== oldValue) { | ||
this.url = newValue | ||
this.fetchAndRenderActorInfo(this.url) | ||
} | ||
} | ||
|
||
async fetchAndRenderActorInfo (url) { | ||
try { | ||
const actorInfo = await db.getActor(url) | ||
if (actorInfo) { | ||
this.renderActorInfo(actorInfo) | ||
} | ||
} catch (error) { | ||
console.error('Error fetching actor info:', error) | ||
} | ||
} | ||
|
||
renderActorInfo (actorInfo) { | ||
// Clear existing content | ||
this.innerHTML = '' | ||
|
||
// Container for the icon and name, which should be a button for clickable actions | ||
const clickableContainer = document.createElement('button') | ||
clickableContainer.className = 'mini-profile' | ||
clickableContainer.setAttribute('type', 'button') | ||
|
||
let iconUrl = './assets/profile.png' | ||
if (actorInfo.icon) { | ||
iconUrl = actorInfo.icon.url || (Array.isArray(actorInfo.icon) ? actorInfo.icon[0].url : iconUrl) | ||
} | ||
|
||
// Actor icon | ||
const img = document.createElement('img') | ||
img.className = 'profile-mini-icon' | ||
img.src = iconUrl | ||
img.alt = actorInfo.name ? actorInfo.name : 'Actor icon' | ||
clickableContainer.appendChild(img) | ||
|
||
// Actor name | ||
if (actorInfo.name) { | ||
const pName = document.createElement('div') | ||
pName.classList.add('profile-mini-name') | ||
pName.textContent = actorInfo.name | ||
clickableContainer.appendChild(pName) | ||
} | ||
|
||
// Append the clickable container | ||
this.appendChild(clickableContainer) | ||
|
||
// Add click event to the clickable container for navigation | ||
clickableContainer.addEventListener('click', () => { | ||
window.location.href = `/profile.html?actor=${encodeURIComponent(this.url)}` | ||
}) | ||
|
||
const pDate = document.createElement('span') | ||
pDate.classList.add('profile-followed-date') | ||
pDate.textContent = ` - Followed At: ${this.getAttribute('followed-at')}` | ||
this.appendChild(pDate) | ||
} | ||
} | ||
|
||
customElements.define('actor-mini-profile', ActorMiniProfile) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
.profile { | ||
margin-top: 20px; | ||
} | ||
|
||
.profile-container { | ||
text-align: center; | ||
} | ||
|
||
.distributed-post-header { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
margin-bottom: 16px; | ||
} | ||
|
||
.profile-icon { | ||
width: 50px; | ||
height: 50px; | ||
border-radius: 50%; | ||
background-color: #000000; | ||
margin-right: 8px; | ||
margin-bottom: 8px; | ||
} | ||
|
||
.profile-details { | ||
display: flex; | ||
flex-direction: column; | ||
} | ||
|
||
.profile-name { | ||
color: var(--rdp-text-color); | ||
font-weight: bold; | ||
} | ||
|
||
.profile-username { | ||
color: var(--rdp-text-color); | ||
margin-top: 1px; | ||
} | ||
|
||
.profile-summary { | ||
color: var(--rdp-details-color); | ||
width: 500px; | ||
margin-left: auto; | ||
margin-right: auto; | ||
margin-top: 8px; | ||
margin-bottom: 10px; | ||
overflow-wrap: break-word; | ||
} | ||
|
||
follow-button { | ||
appearance: none; | ||
border: 1px solid var(--rdp-border-color); | ||
border-radius: 4px; | ||
box-shadow: rgba(27, 31, 35, 0.1) 0 1px 0; | ||
box-sizing: border-box; | ||
cursor: pointer; | ||
display: inline-block; | ||
font-family: inherit; | ||
font-size: inherit; | ||
font-weight: 600; | ||
line-height: 20px; | ||
padding: 4px 16px; | ||
position: relative; | ||
text-align: center; | ||
text-decoration: none; | ||
touch-action: manipulation; | ||
vertical-align: middle; | ||
white-space: nowrap; | ||
} | ||
|
||
follow-button[state="follow"], | ||
follow-button[state="unfollow"] { | ||
color: #fff; | ||
} | ||
|
||
follow-button[state="follow"] { | ||
background-color: #3b82f6; | ||
} | ||
follow-button[state="follow"]:hover { | ||
background-color: #2563eb; | ||
} | ||
|
||
follow-button[state="unfollow"] { | ||
background-color: #ef4444; | ||
} | ||
follow-button[state="unfollow"]:hover { | ||
background-color: #dc2626; | ||
} | ||
|
||
.actor-profile { | ||
flex: 1; | ||
max-width: 600px; | ||
width: 100%; | ||
margin: 0 20px; | ||
} | ||
|
||
@media (max-width: 768px) { | ||
.profile-summary { | ||
width: 100%; | ||
} | ||
} |
Oops, something went wrong.