parent
f6078b66e0
commit
9d4572d3d8
@ -0,0 +1,28 @@ |
||||
"""Added article ratings. |
||||
|
||||
Revision ID: 21ec84874208 |
||||
Revises: 3d58e8ebf8c6 |
||||
Create Date: 2020-03-19 01:10:12.194485 |
||||
|
||||
""" |
||||
from alembic import op |
||||
import sqlalchemy as sa |
||||
|
||||
|
||||
# revision identifiers, used by Alembic. |
||||
revision = '21ec84874208' |
||||
down_revision = '3d58e8ebf8c6' |
||||
branch_labels = None |
||||
depends_on = None |
||||
|
||||
|
||||
def upgrade(): |
||||
# ### commands auto generated by Alembic - please adjust! ### |
||||
op.add_column('article', sa.Column('article_rating', sa.Integer(), nullable=True)) |
||||
# ### end Alembic commands ### |
||||
|
||||
|
||||
def downgrade(): |
||||
# ### commands auto generated by Alembic - please adjust! ### |
||||
op.drop_column('article', 'article_rating') |
||||
# ### end Alembic commands ### |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 6.0 KiB |
@ -0,0 +1,2 @@ |
||||
.rating-stars { float: right ; margin-top: -0.1em ; margin-right: 0.25em ; } |
||||
.rating-stars img { height: 0.75em ; margin-right: 0.1em ; cursor: pointer ; } |
@ -0,0 +1,63 @@ |
||||
import React from "react" ; |
||||
import "./RatingStars.css" ; |
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
export class RatingStars extends React.Component |
||||
{ |
||||
|
||||
constructor( props ) { |
||||
// initialize
|
||||
super( props ) ; |
||||
this.state = { |
||||
rating: props.rating, |
||||
} ; |
||||
} |
||||
|
||||
render() { |
||||
|
||||
let changeRating = ( starIndex ) => { |
||||
// update the rating
|
||||
let newRating ; |
||||
if ( starRefs[starIndex].src.indexOf( "rating-star-disabled.png" ) !== -1 ) |
||||
newRating = starIndex + 1 ; |
||||
else { |
||||
// NOTE: We get here if the clicked-on star is enabled. If this is the highest enabled star,
|
||||
// we disable it (i.e. set the rating to N-1), otherwise we make it the highest star (i.e. set
|
||||
// the rating to N). This has the down-side that if the user wants to set a rating of 0,
|
||||
// they have to set the rating to 1 first, then set it to 0, but this is unlikely to be an issue
|
||||
// i.e. going from 1 to 0 will be far more common than 3 to 0.
|
||||
if ( starIndex+1 === this.state.rating ) |
||||
newRating = starIndex ; |
||||
else |
||||
newRating = starIndex + 1 ; |
||||
} |
||||
const prevRating = this.state.rating ; |
||||
this.setState( { rating: newRating } ) ; |
||||
// notify the parent
|
||||
if ( this.props.onChange ) { |
||||
this.props.onChange( newRating, () => { |
||||
this.setState( { rating: prevRating } ) ; // nb: the update failed, rollback
|
||||
} ) ; |
||||
} |
||||
} |
||||
|
||||
// prepare the rating stars
|
||||
let stars=[], starRefs={} ; |
||||
for ( let i=0 ; i < 3 ; ++i ) { |
||||
const fname = this.state.rating > i ? "rating-star.png" : "rating-star-disabled.png" ; |
||||
stars.push( |
||||
<img src={"/images/"+fname} key={i} alt="Rating star." |
||||
ref = { r => starRefs[i] = r } |
||||
onClick={ () => changeRating(i) } |
||||
/> |
||||
) ; |
||||
} |
||||
|
||||
// render the component
|
||||
return ( <span className="rating-stars" title={this.props.title} > |
||||
{stars} |
||||
</span> ) ; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue