Files
easystream-main/docs/QUICK_START_GUIDE.md
SamiAhmed7777 f0f346deb9
Some checks failed
EasyStream Test Suite / test (pull_request) Has been cancelled
EasyStream Test Suite / code-quality (pull_request) Has been cancelled
EasyStream Test Suite / integration-test (pull_request) Has been cancelled
Sync current dev state
2025-12-15 17:28:21 -08:00

595 lines
13 KiB
Markdown

# EasyStream API Quick Start Guide
## Get Started in 5 Minutes
This guide will get you up and running with the EasyStream API quickly.
## Prerequisites
- EasyStream installed and running
- Modern web browser
- Basic JavaScript knowledge
---
## 1. Authentication
### Login and Get Token
```javascript
// The API client is automatically available as 'api'
const result = await api.login('myusername', 'mypassword');
if (result.success) {
console.log('Logged in!');
console.log('User:', result.user);
console.log('Token:', result.token);
// Token is automatically stored
}
```
### Check if Logged In
```javascript
if (api.isAuthenticated()) {
console.log('User is logged in');
} else {
console.log('Please log in');
}
```
---
## 2. Working with Videos
### List Videos
```javascript
const videos = await api.getVideos({
page: 1,
limit: 20,
sort: 'popular'
});
console.log('Videos:', videos.data.videos);
```
### Get Single Video
```javascript
const video = await api.getVideo('123456');
console.log('Video:', video.data);
```
### Search Videos
```javascript
const results = await api.searchVideos('funny cats');
console.log('Found:', results.data.videos);
```
### Like a Video
```javascript
await api.likeVideo('123456', 'like');
console.log('Video liked!');
```
### Create a Video
```javascript
const newVideo = await api.createVideo({
title: 'My Awesome Video',
description: 'This is a great video',
privacy: 'public',
category: 'entertainment'
});
console.log('Created video:', newVideo.data.file_key);
```
---
## 3. User Profiles
### Get Current User Profile
```javascript
const myProfile = await api.getMyProfile();
console.log('My profile:', myProfile.data);
```
### Get Another User's Profile
```javascript
const userProfile = await api.getUserProfile(123);
console.log('User:', userProfile.data);
```
### Update Profile
```javascript
await api.updateProfile({
usr_dname: 'My New Name',
usr_about: 'I love making videos!'
});
console.log('Profile updated!');
```
### Upload Avatar
```html
<input type="file" id="avatar-input" accept="image/*">
<button onclick="uploadAvatar()">Upload</button>
<script>
async function uploadAvatar() {
const fileInput = document.getElementById('avatar-input');
const file = fileInput.files[0];
if (file) {
const result = await api.uploadAvatar(file);
console.log('Avatar uploaded:', result.data.avatar_url);
}
}
</script>
```
---
## 4. Comments
### Get Comments for a Video
```javascript
const comments = await api.getComments('123456', {
page: 1,
sort: 'recent'
});
console.log('Comments:', comments.data.comments);
```
### Post a Comment
```javascript
const newComment = await api.createComment(
'123456', // video file_key
'Great video!', // comment text
null // parent_id (null for top-level)
);
console.log('Comment posted:', newComment.data);
```
### Reply to a Comment
```javascript
const reply = await api.createComment(
'123456', // video file_key
'Thanks!', // reply text
789 // parent comment ID
);
console.log('Reply posted:', reply.data);
```
---
## 5. Subscriptions
### Subscribe to a Channel
```javascript
await api.subscribe(456); // channel user ID
console.log('Subscribed!');
```
### Check if Subscribed
```javascript
const status = await api.checkSubscription(456);
if (status.data.is_subscribed) {
console.log('Already subscribed');
} else {
console.log('Not subscribed');
}
```
### Get Subscription Feed
```javascript
const feed = await api.getSubscriptionFeed({ page: 1 });
console.log('New videos from subscriptions:', feed.data.videos);
```
---
## 6. Complete Examples
### Video Player Page
```html
<!DOCTYPE html>
<html>
<head>
<title>Watch Video</title>
<style>
.video-container { max-width: 800px; margin: 0 auto; }
.actions button { margin: 5px; }
.comments { margin-top: 20px; }
</style>
</head>
<body>
<div class="video-container">
<h1 id="video-title"></h1>
<p id="video-description"></p>
<div class="actions">
<button id="like-btn">👍 Like</button>
<button id="subscribe-btn">Subscribe</button>
<button id="watch-later-btn">⏰ Watch Later</button>
</div>
<div class="comments">
<h2>Comments</h2>
<div id="comments-list"></div>
<form id="comment-form">
<textarea id="comment-text" placeholder="Add a comment..." required></textarea>
<button type="submit">Post Comment</button>
</form>
</div>
</div>
<script src="/f_scripts/fe/js/api-helper.js"></script>
<script>
const fileKey = '123456'; // Get from URL
// Load video and comments
async function init() {
try {
// Load video
const video = await api.getVideo(fileKey);
document.getElementById('video-title').textContent = video.data.file_title;
document.getElementById('video-description').textContent = video.data.file_description;
// Record view
await api.recordVideoView(fileKey);
// Load comments
await loadComments();
// Setup buttons
setupButtons(video.data);
} catch (error) {
api.handleError(error);
}
}
async function loadComments() {
const comments = await api.getComments(fileKey);
const list = document.getElementById('comments-list');
list.innerHTML = comments.data.comments.map(c => `
<div class="comment">
<strong>${c.usr_dname}</strong>
<p>${c.comment_text}</p>
<small>${c.comment_date}</small>
</div>
`).join('');
}
function setupButtons(video) {
// Like button
document.getElementById('like-btn').addEventListener('click', async () => {
await api.likeVideo(fileKey, 'like');
alert('Video liked!');
});
// Subscribe button
document.getElementById('subscribe-btn').addEventListener('click', async () => {
await api.subscribe(video.usr_id);
alert('Subscribed!');
});
// Watch later button
document.getElementById('watch-later-btn').addEventListener('click', async () => {
await api.toggleWatchLater(fileKey);
alert('Added to Watch Later!');
});
// Comment form
document.getElementById('comment-form').addEventListener('submit', async (e) => {
e.preventDefault();
const text = document.getElementById('comment-text').value;
await api.createComment(fileKey, text);
document.getElementById('comment-text').value = '';
await loadComments();
});
}
// Start
init();
</script>
</body>
</html>
```
### Browse Videos Page
```html
<!DOCTYPE html>
<html>
<head>
<title>Browse Videos</title>
<style>
.video-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; }
.video-card { border: 1px solid #ddd; padding: 15px; }
.filters { margin-bottom: 20px; }
</style>
</head>
<body>
<div class="container">
<h1>Browse Videos</h1>
<div class="filters">
<select id="sort-select">
<option value="recent">Recent</option>
<option value="popular">Popular</option>
<option value="featured">Featured</option>
</select>
<input type="text" id="search-input" placeholder="Search videos...">
<button id="search-btn">Search</button>
</div>
<div class="video-grid" id="video-grid"></div>
<button id="load-more">Load More</button>
</div>
<script src="/f_scripts/fe/js/api-helper.js"></script>
<script>
let currentPage = 1;
let currentSort = 'recent';
let searchQuery = '';
async function loadVideos(append = false) {
try {
let result;
if (searchQuery) {
result = await api.searchVideos(searchQuery, {
page: currentPage,
limit: 20
});
} else {
result = await api.getVideos({
page: currentPage,
limit: 20,
sort: currentSort
});
}
displayVideos(result.data.videos, append);
// Show/hide load more button
const loadMoreBtn = document.getElementById('load-more');
if (currentPage >= result.data.pagination.pages) {
loadMoreBtn.style.display = 'none';
} else {
loadMoreBtn.style.display = 'block';
}
} catch (error) {
api.handleError(error);
}
}
function displayVideos(videos, append = false) {
const grid = document.getElementById('video-grid');
if (!append) {
grid.innerHTML = '';
}
videos.forEach(video => {
const card = document.createElement('div');
card.className = 'video-card';
card.innerHTML = `
<h3>${video.file_title}</h3>
<p>${video.file_description}</p>
<p>
<small>
By ${video.usr_dname}
${video.file_views} views •
${video.like_count} likes
</small>
</p>
<button onclick="watchVideo('${video.file_key}')">
Watch
</button>
`;
grid.appendChild(card);
});
}
window.watchVideo = function(fileKey) {
window.location.href = `/watch.php?v=${fileKey}`;
};
// Sort change
document.getElementById('sort-select').addEventListener('change', (e) => {
currentSort = e.target.value;
currentPage = 1;
loadVideos(false);
});
// Search
document.getElementById('search-btn').addEventListener('click', () => {
searchQuery = document.getElementById('search-input').value;
currentPage = 1;
loadVideos(false);
});
// Load more
document.getElementById('load-more').addEventListener('click', () => {
currentPage++;
loadVideos(true);
});
// Initial load
loadVideos();
</script>
</body>
</html>
```
---
## 7. Error Handling
Always wrap API calls in try-catch:
```javascript
try {
const result = await api.someAPICall();
// Handle success
} catch (error) {
// Handle error
console.error('Error:', error.message);
// Use built-in error handler
api.handleError(error);
// Or custom handling
if (error.message.includes('Authentication')) {
window.location.href = '/signin';
} else {
alert('Error: ' + error.message);
}
}
```
---
## 8. Common Patterns
### Loading State
```javascript
async function loadData() {
showLoading(); // Your loading function
try {
const result = await api.getVideos();
displayData(result.data);
} catch (error) {
api.handleError(error);
} finally {
hideLoading(); // Always hide loading
}
}
```
### Infinite Scroll
```javascript
let currentPage = 1;
let loading = false;
window.addEventListener('scroll', async () => {
if (loading) return;
const scrolledToBottom =
window.innerHeight + window.scrollY >= document.body.offsetHeight - 500;
if (scrolledToBottom) {
loading = true;
currentPage++;
try {
const result = await api.getVideos({ page: currentPage });
appendVideos(result.data.videos);
} catch (error) {
api.handleError(error);
} finally {
loading = false;
}
}
});
```
### Debounced Search
```javascript
let searchTimeout;
document.getElementById('search-input').addEventListener('input', (e) => {
clearTimeout(searchTimeout);
searchTimeout = setTimeout(async () => {
const query = e.target.value;
if (query.length >= 2) {
const results = await api.searchVideos(query);
displaySearchResults(results.data.videos);
}
}, 300); // Wait 300ms after user stops typing
});
```
---
## 9. Browser Console Testing
Test API calls directly in the browser console:
```javascript
// Check authentication
api.isAuthenticated()
// Login
await api.login('username', 'password')
// Get videos
await api.getVideos({ page: 1 })
// Get current user
await api.getMyProfile()
// View stored token
localStorage.getItem('jwt_token')
// Clear token
api.clearToken()
```
---
## 10. Next Steps
- Read [API_DOCUMENTATION.md](API_DOCUMENTATION.md) for complete reference
- Check [FRONTEND_BACKEND_INTEGRATION_GUIDE.md](FRONTEND_BACKEND_INTEGRATION_GUIDE.md) for advanced patterns
- Review example code in [f_scripts/fe/js/api-helper.js](../f_scripts/fe/js/api-helper.js)
---
## Support
If you encounter issues:
1. Check browser console for errors
2. Check Network tab to see API requests/responses
3. Verify you're logged in: `api.isAuthenticated()`
4. Check API documentation for correct parameters
---
**Last Updated:** January 2025